Fixing up notification testing (#575)
This commit is contained in:
parent
be1415fbd4
commit
a4b32b0d31
|
@ -207,7 +207,8 @@ class CertificateNotificationOutputSchema(LemurOutputSchema):
|
||||||
name = fields.String()
|
name = fields.String()
|
||||||
owner = fields.Email()
|
owner = fields.Email()
|
||||||
user = fields.Nested(UserNestedOutputSchema)
|
user = fields.Nested(UserNestedOutputSchema)
|
||||||
replaces = fields.Nested(CertificateNestedOutputSchema, many=True)
|
validity_end = ArrowDateTime(attribute='not_after')
|
||||||
|
replaced = fields.Nested(CertificateNestedOutputSchema, many=True)
|
||||||
endpoints = fields.Nested(EndpointNestedOutputSchema, many=True, missing=[])
|
endpoints = fields.Nested(EndpointNestedOutputSchema, many=True, missing=[])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ def send_expiration_notifications():
|
||||||
This function will check for upcoming certificate expiration,
|
This function will check for upcoming certificate expiration,
|
||||||
and send out notification emails at given intervals.
|
and send out notification emails at given intervals.
|
||||||
"""
|
"""
|
||||||
|
sent = 0
|
||||||
for plugin in plugins.all(plugin_type='notification'):
|
for plugin in plugins.all(plugin_type='notification'):
|
||||||
notifications = database.db.session.query(Notification)\
|
notifications = database.db.session.query(Notification)\
|
||||||
.filter(Notification.plugin_name == plugin.slug)\
|
.filter(Notification.plugin_name == plugin.slug)\
|
||||||
|
@ -36,16 +37,18 @@ def send_expiration_notifications():
|
||||||
data = certificate_notification_output_schema.dump(certificate).data
|
data = certificate_notification_output_schema.dump(certificate).data
|
||||||
messages.append((data, n.options))
|
messages.append((data, n.options))
|
||||||
|
|
||||||
for data, targets, options in messages:
|
for data, options in messages:
|
||||||
try:
|
try:
|
||||||
plugin.send('expiration', data, targets, options)
|
plugin.send('expiration', data, [data['owner']], options)
|
||||||
metrics.send('expiration_notification_sent', 'counter', 1)
|
metrics.send('expiration_notification_sent', 'counter', 1)
|
||||||
|
sent += 1
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
metrics.send('expiration_notification_failure', 'counter', 1)
|
metrics.send('expiration_notification_failure', 'counter', 1)
|
||||||
current_app.logger.exception(e)
|
current_app.logger.exception(e)
|
||||||
|
return sent
|
||||||
|
|
||||||
|
|
||||||
def send_rotation_notification(certificate):
|
def send_rotation_notification(certificate, notification_plugin=None):
|
||||||
"""
|
"""
|
||||||
Sends a report to certificate owners when their certificate as been
|
Sends a report to certificate owners when their certificate as been
|
||||||
rotated.
|
rotated.
|
||||||
|
@ -53,12 +56,13 @@ def send_rotation_notification(certificate):
|
||||||
:param certificate:
|
:param certificate:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
plugin = plugins.get(current_app.config.get('LEMUR_DEFAULT_NOTIFICATION_PLUGIN'))
|
if not notification_plugin:
|
||||||
|
notification_plugin = plugins.get(current_app.config.get('LEMUR_DEFAULT_NOTIFICATION_PLUGIN'))
|
||||||
|
|
||||||
data = certificate_notification_output_schema.dump(certificate).data
|
data = certificate_notification_output_schema.dump(certificate).data
|
||||||
|
|
||||||
try:
|
try:
|
||||||
plugin.send('rotation', data, [data.owner])
|
notification_plugin.send('rotation', data, [data['owner']])
|
||||||
metrics.send('rotation_notification_sent', 'counter', 1)
|
metrics.send('rotation_notification_sent', 'counter', 1)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
metrics.send('rotation_notification_failure', 'counter', 1)
|
metrics.send('rotation_notification_failure', 'counter', 1)
|
||||||
|
|
|
@ -16,7 +16,7 @@ class NotificationPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
type = 'notification'
|
type = 'notification'
|
||||||
|
|
||||||
def send(self):
|
def send(self, notification_type, message, targets, options, **kwargs):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,5 +48,5 @@ class ExpirationNotificationPlugin(NotificationPlugin):
|
||||||
def options(self):
|
def options(self):
|
||||||
return list(self.default_options) + self.additional_options
|
return list(self.default_options) + self.additional_options
|
||||||
|
|
||||||
def send(self):
|
def send(self, notification_type, message, targets, options, **kwargs):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
|
@ -85,10 +85,10 @@ class EmailNotificationPlugin(ExpirationNotificationPlugin):
|
||||||
raise InvalidConfiguration('Email sender type {0} is not recognized.')
|
raise InvalidConfiguration('Email sender type {0} is not recognized.')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def send(template_name, message, targets, **kwargs):
|
def send(notification_type, message, targets, options, **kwargs):
|
||||||
subject = 'Lemur: Expiration Notification'
|
subject = 'Lemur: {0} Notification'.format(notification_type.capitalize())
|
||||||
|
|
||||||
body = render_html(template_name, message)
|
body = render_html(notification_type, message)
|
||||||
|
|
||||||
s_type = current_app.config.get("LEMUR_EMAIL_SENDER", 'ses').lower()
|
s_type = current_app.config.get("LEMUR_EMAIL_SENDER", 'ses').lower()
|
||||||
|
|
||||||
|
|
|
@ -79,18 +79,18 @@
|
||||||
<table border="0" cellspacing="0" cellpadding="0"
|
<table border="0" cellspacing="0" cellpadding="0"
|
||||||
style="margin-top:48px;margin-bottom:48px">
|
style="margin-top:48px;margin-bottom:48px">
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for message in messages %}
|
{% for certificate in certificates %}
|
||||||
<tr valign="middle">
|
<tr valign="middle">
|
||||||
<td width="32px"></td>
|
<td width="32px"></td>
|
||||||
<td width="16px"></td>
|
<td width="16px"></td>
|
||||||
<td style="line-height:1.2">
|
<td style="line-height:1.2">
|
||||||
<span style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:20px;color:#202020">{{ message.name }}</span>
|
<span style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:20px;color:#202020">{{ certificate.name }}</span>
|
||||||
<br>
|
<br>
|
||||||
<span style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:13px;color:#727272">
|
<span style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:13px;color:#727272">
|
||||||
{{ message.endpoints | length }} Endpoints
|
{{ certificate.endpoints | length }} Endpoints
|
||||||
<br>{{ message.owner }}
|
<br>{{ certificate.owner }}
|
||||||
<br>{{ message.not_after | time }}
|
<br>{{ certificate.validityEnd | time }}
|
||||||
<a href="https://{{ hostname }}/#/certificates/{{ message.name }}" target="_blank">Details</a>
|
<a href="https://{{ hostname }}/#/certificates/{{ certificate.name }}" target="_blank">Details</a>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td width="32px"></td>
|
<td width="32px"></td>
|
||||||
<td style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:24px;color:#ffffff;line-height:1.25">
|
<td style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:24px;color:#ffffff;line-height:1.25">
|
||||||
Your certificate(s) have been rotated!
|
Your certificate has been rotated!
|
||||||
</td>
|
</td>
|
||||||
<td width="32px"></td>
|
<td width="32px"></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -74,44 +74,31 @@
|
||||||
<br>This is a Lemur certificate rotation notice. Your certificate has been re-issued and re-provisioned.
|
<br>This is a Lemur certificate rotation notice. Your certificate has been re-issued and re-provisioned.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:20px;color:#202020;line-height:1.5">
|
|
||||||
Impacted Certificate:
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:13px;color:#202020;line-height:1.5">
|
<td style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:13px;color:#202020;line-height:1.5">
|
||||||
<table border="0" cellspacing="0" cellpadding="0"
|
<table border="0" cellspacing="0" cellpadding="0"
|
||||||
style="margin-top:48px;margin-bottom:48px">
|
style="margin-top:48px;margin-bottom:48px">
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for message in messages %}
|
|
||||||
<tr valign="middle">
|
<tr valign="middle">
|
||||||
<td width="32px"></td>
|
<td width="32px"></td>
|
||||||
<td width="16px"></td>
|
<td width="16px"></td>
|
||||||
<td style="line-height:1.2">
|
<td style="line-height:1.2">
|
||||||
<span style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:20px;color:#202020">{{ message.name }}</span>
|
<span style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:20px;color:#202020">{{ certificate.name }}</span>
|
||||||
<br>
|
<br>
|
||||||
<span style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:13px;color:#727272">
|
<span style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:13px;color:#727272">
|
||||||
{{ message.endpoints | length }} Endpoints
|
<br>{{ certificate.owner }}
|
||||||
<br>{{ message.owner }}
|
<br>{{ certificate.validityEnd | time }}
|
||||||
<br>{{ message.not_after | time }}
|
<a href="https://{{ hostname }}/#/certificates/{{ certificate.name }}" target="_blank">Details</a>
|
||||||
<a href="https://{{ hostname }}/#/certificates/{{ message.name }}" target="_blank">Details</a>
|
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% if not loop.last %}
|
|
||||||
<tr valign="middle">
|
|
||||||
<td width="32px" height="24px"></td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:20px;color:#202020;line-height:1.5">
|
<td style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:15px;color:#202020;line-height:1.5">
|
||||||
Impacted Endpoints:
|
Replaced by:
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -119,18 +106,43 @@
|
||||||
<table border="0" cellspacing="0" cellpadding="0"
|
<table border="0" cellspacing="0" cellpadding="0"
|
||||||
style="margin-top:48px;margin-bottom:48px">
|
style="margin-top:48px;margin-bottom:48px">
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for message in messages %}
|
<tr valign="middle">
|
||||||
|
<td width="32px"></td>
|
||||||
|
<td width="16px"></td>
|
||||||
|
<td style="line-height:1.2">
|
||||||
|
<span style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:20px;color:#202020">{{ certificate.replaced.name }}</span>
|
||||||
|
<br>
|
||||||
|
<span style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:13px;color:#727272">
|
||||||
|
<br>{{ certificate.replaced[0].owner }}
|
||||||
|
<br>{{ certificate.replaced[0].validityEnd | time }}
|
||||||
|
<a href="https://{{ hostname }}/#/certificates/{{ certificate.replaced[0].name }}" target="_blank">Details</a>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:15px;color:#202020;line-height:1.5">
|
||||||
|
Endpoints Rotated:
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:13px;color:#202020;line-height:1.5">
|
||||||
|
<table border="0" cellspacing="0" cellpadding="0"
|
||||||
|
style="margin-top:48px;margin-bottom:48px">
|
||||||
|
<tbody>
|
||||||
|
{% for endpoint in certificate.endpoints %}
|
||||||
<tr valign="middle">
|
<tr valign="middle">
|
||||||
<td width="32px"></td>
|
<td width="32px"></td>
|
||||||
<td width="16px"></td>
|
<td width="16px"></td>
|
||||||
<td style="line-height:1.2">
|
<td style="line-height:1.2">
|
||||||
<span style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:20px;color:#202020">{{ message.name }}</span>
|
<span style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:20px;color:#202020">{{ endpoint.name }}</span>
|
||||||
<br>
|
<br>
|
||||||
<span style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:13px;color:#727272">
|
<span style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:13px;color:#727272">
|
||||||
{{ message.endpoints | length }} Endpoints
|
<br>{{ endpoint.dnsname }} | {{ endpoint.port }}
|
||||||
<br>{{ message.owner }}
|
<a href="https://{{ hostname }}/#/endpoints/{{ endpoint.name }}" target="_blank">Details</a>
|
||||||
<br>{{ message.not_after | time }}
|
|
||||||
<a href="https://{{ hostname }}/#/certificates/{{ message.name }}" target="_blank">Details</a>
|
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
from lemur.tests.conftest import * # noqa
|
|
@ -1,12 +1,34 @@
|
||||||
|
import os
|
||||||
from lemur.plugins.lemur_email.templates.config import env
|
from lemur.plugins.lemur_email.templates.config import env
|
||||||
|
|
||||||
|
from lemur.tests.factories import CertificateFactory
|
||||||
|
|
||||||
def test_render():
|
dir_path = os.path.dirname(os.path.realpath(__file__))
|
||||||
messages = [{
|
|
||||||
'name': 'a-really-really-long-certificate-name',
|
|
||||||
'owner': 'bob@example.com',
|
def test_render(certificate, endpoint):
|
||||||
'not_after': '2015-12-14 23:59:59'
|
from lemur.certificates.schemas import certificate_notification_output_schema
|
||||||
}] * 10
|
|
||||||
|
new_cert = CertificateFactory()
|
||||||
|
new_cert.replaces.append(certificate)
|
||||||
|
|
||||||
|
certificates = [certificate_notification_output_schema.dump(certificate).data]
|
||||||
|
|
||||||
template = env.get_template('{}.html'.format('expiration'))
|
template = env.get_template('{}.html'.format('expiration'))
|
||||||
body = template.render(dict(messages=messages, hostname='lemur.test.example.com'))
|
|
||||||
|
with open(os.path.join(dir_path, 'expiration-rendered.html'), 'w') as f:
|
||||||
|
body = template.render(dict(certificates=certificates, hostname='lemur.test.example.com'))
|
||||||
|
f.write(body)
|
||||||
|
|
||||||
|
template = env.get_template('{}.html'.format('rotation'))
|
||||||
|
|
||||||
|
certificate.endpoints.append(endpoint)
|
||||||
|
|
||||||
|
with open(os.path.join(dir_path, 'rotation-rendered.html'), 'w') as f:
|
||||||
|
body = template.render(
|
||||||
|
dict(
|
||||||
|
certificate=certificate_notification_output_schema.dump(certificate).data,
|
||||||
|
hostname='lemur.test.example.com'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
f.write(body)
|
||||||
|
|
|
@ -23,28 +23,28 @@ def create_certificate_url(name):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_expiration_attachments(messages):
|
def create_expiration_attachments(certificates):
|
||||||
attachments = []
|
attachments = []
|
||||||
for message in messages:
|
for certificate in certificates:
|
||||||
attachments.append({
|
attachments.append({
|
||||||
'title': message['name'],
|
'title': certificate['name'],
|
||||||
'title_link': create_certificate_url(message['name']),
|
'title_link': create_certificate_url(certificate['name']),
|
||||||
'color': 'danger',
|
'color': 'danger',
|
||||||
'fallback': '',
|
'fallback': '',
|
||||||
'fields': [
|
'fields': [
|
||||||
{
|
{
|
||||||
'title': 'Owner',
|
'title': 'Owner',
|
||||||
'value': message['owner'],
|
'value': certificate['owner'],
|
||||||
'short': True
|
'short': True
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'title': 'Expires',
|
'title': 'Expires',
|
||||||
'value': arrow.get(message['not_after']).format('dddd, MMMM D, YYYY'),
|
'value': arrow.get(certificate['validityEnd']).format('dddd, MMMM D, YYYY'),
|
||||||
'short': True
|
'short': True
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'title': 'Endpoints Detected',
|
'title': 'Endpoints Detected',
|
||||||
'value': len(message['endpoints']),
|
'value': len(certificate['endpoints']),
|
||||||
'short': True
|
'short': True
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -54,6 +54,37 @@ def create_expiration_attachments(messages):
|
||||||
return attachments
|
return attachments
|
||||||
|
|
||||||
|
|
||||||
|
def create_rotation_attachments(certificate):
|
||||||
|
return {
|
||||||
|
'title': certificate['name'],
|
||||||
|
'title_link': create_certificate_url(certificate['name']),
|
||||||
|
'fields': [
|
||||||
|
{
|
||||||
|
{
|
||||||
|
'title': 'Owner',
|
||||||
|
'value': certificate['owner'],
|
||||||
|
'short': True
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'title': 'Expires',
|
||||||
|
'value': arrow.get(certificate['validityEnd']).format('dddd, MMMM D, YYYY'),
|
||||||
|
'short': True
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'title': 'Replaced By',
|
||||||
|
'value': len(certificate['replaced'][0]['name']),
|
||||||
|
'short': True
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'title': 'Endpoints Rotated',
|
||||||
|
'value': len(certificate['endpoints']),
|
||||||
|
'short': True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class SlackNotificationPlugin(ExpirationNotificationPlugin):
|
class SlackNotificationPlugin(ExpirationNotificationPlugin):
|
||||||
title = 'Slack'
|
title = 'Slack'
|
||||||
slug = 'slack-notification'
|
slug = 'slack-notification'
|
||||||
|
@ -85,25 +116,31 @@ class SlackNotificationPlugin(ExpirationNotificationPlugin):
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
def send(self, event_type, message, targets, options, **kwargs):
|
def send(self, notification_type, message, targets, options, **kwargs):
|
||||||
"""
|
"""
|
||||||
A typical check can be performed using the notify command:
|
A typical check can be performed using the notify command:
|
||||||
`lemur notify`
|
`lemur notify`
|
||||||
"""
|
"""
|
||||||
if event_type == 'expiration':
|
attachments = None
|
||||||
|
if notification_type == 'expiration':
|
||||||
attachments = create_expiration_attachments(message)
|
attachments = create_expiration_attachments(message)
|
||||||
|
|
||||||
|
elif notification_type == 'rotation':
|
||||||
|
attachments = create_rotation_attachments(message)
|
||||||
|
|
||||||
if not attachments:
|
if not attachments:
|
||||||
raise Exception('Unable to create message attachments')
|
raise Exception('Unable to create message attachments')
|
||||||
|
|
||||||
body = {
|
body = {
|
||||||
'text': 'Lemur Expiration Notification',
|
'text': 'Lemur {0} Notification'.format(notification_type.capitalize()),
|
||||||
'attachments': attachments,
|
'attachments': attachments,
|
||||||
'channel': self.get_option('recipients', options),
|
'channel': self.get_option('recipients', options),
|
||||||
'username': self.get_option('username', options)
|
'username': self.get_option('username', options)
|
||||||
}
|
}
|
||||||
|
|
||||||
r = requests.post(self.get_option('webhook', options), json.dumps(body))
|
r = requests.post(self.get_option('webhook', options), json.dumps(body))
|
||||||
|
|
||||||
if r.status_code not in [200]:
|
if r.status_code not in [200]:
|
||||||
raise Exception('Failed to send message')
|
raise Exception('Failed to send message')
|
||||||
|
|
||||||
current_app.logger.error("Slack response: {0} Message Body: {1}".format(r.status_code, body))
|
current_app.logger.error("Slack response: {0} Message Body: {1}".format(r.status_code, body))
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
def test_formatting(certificate):
|
def test_formatting(certificate):
|
||||||
from lemur.plugins.lemur_slack.plugin import create_expiration_attachments
|
from lemur.plugins.lemur_slack.plugin import create_expiration_attachments
|
||||||
from lemur.notifications.service import _get_message_data
|
from lemur.certificates.schemas import certificate_notification_output_schema
|
||||||
data = [_get_message_data(certificate)]
|
data = [certificate_notification_output_schema.dump(certificate).data]
|
||||||
|
|
||||||
attachment = {
|
attachment = {
|
||||||
'title': certificate.name,
|
'title': certificate.name,
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
import unittest
|
|
||||||
|
|
||||||
|
|
||||||
class LemurTestCase(unittest.TestCase):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class LemurPluginTestCase(LemurTestCase):
|
|
||||||
pass
|
|
|
@ -1,16 +1,12 @@
|
||||||
import os
|
import os
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from flask import current_app
|
|
||||||
|
|
||||||
from flask_principal import identity_changed, Identity
|
|
||||||
|
|
||||||
from lemur import create_app
|
from lemur import create_app
|
||||||
from lemur.database import db as _db
|
from lemur.database import db as _db
|
||||||
from lemur.auth.service import create_token
|
from lemur.auth.service import create_token
|
||||||
|
|
||||||
from .factories import AuthorityFactory, NotificationFactory, DestinationFactory, \
|
from .factories import AuthorityFactory, NotificationFactory, DestinationFactory, \
|
||||||
CertificateFactory, UserFactory, RoleFactory, SourceFactory
|
CertificateFactory, UserFactory, RoleFactory, SourceFactory, EndpointFactory
|
||||||
|
|
||||||
|
|
||||||
def pytest_runtest_setup(item):
|
def pytest_runtest_setup(item):
|
||||||
|
@ -114,6 +110,14 @@ def certificate(session):
|
||||||
return c
|
return c
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def endpoint(session):
|
||||||
|
s = SourceFactory()
|
||||||
|
e = EndpointFactory(source=s)
|
||||||
|
session.commit()
|
||||||
|
return e
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def role(session):
|
def role(session):
|
||||||
r = RoleFactory()
|
r = RoleFactory()
|
||||||
|
@ -171,17 +175,3 @@ def source_plugin():
|
||||||
from .plugins.source_plugin import TestSourcePlugin
|
from .plugins.source_plugin import TestSourcePlugin
|
||||||
register(TestSourcePlugin)
|
register(TestSourcePlugin)
|
||||||
return TestSourcePlugin
|
return TestSourcePlugin
|
||||||
|
|
||||||
|
|
||||||
@pytest.yield_fixture(scope="function")
|
|
||||||
def logged_in_user(session, app):
|
|
||||||
with app.test_request_context():
|
|
||||||
identity_changed.send(current_app._get_current_object(), identity=Identity(1))
|
|
||||||
yield
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.yield_fixture(scope="function")
|
|
||||||
def logged_in_admin(session, app):
|
|
||||||
with app.test_request_context():
|
|
||||||
identity_changed.send(current_app._get_current_object(), identity=Identity(2))
|
|
||||||
yield
|
|
||||||
|
|
|
@ -240,6 +240,7 @@ class EndpointFactory(BaseFactory):
|
||||||
type = FuzzyChoice(['elb'])
|
type = FuzzyChoice(['elb'])
|
||||||
active = True
|
active = True
|
||||||
port = FuzzyInteger(0, high=65535)
|
port = FuzzyInteger(0, high=65535)
|
||||||
|
dnsname = 'endpoint.example.com'
|
||||||
policy = SubFactory(PolicyFactory)
|
policy = SubFactory(PolicyFactory)
|
||||||
certificate = SubFactory(CertificateFactory)
|
certificate = SubFactory(CertificateFactory)
|
||||||
source = SubFactory(SourceFactory)
|
source = SubFactory(SourceFactory)
|
||||||
|
|
|
@ -13,5 +13,5 @@ class TestNotificationPlugin(NotificationPlugin):
|
||||||
super(TestNotificationPlugin, self).__init__(*args, **kwargs)
|
super(TestNotificationPlugin, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def send(event_type, message, targets, options, **kwargs):
|
def send(notification_type, message, targets, options, **kwargs):
|
||||||
return
|
return
|
||||||
|
|
|
@ -354,7 +354,7 @@ def test_get_account_number(client):
|
||||||
assert get_account_number(arn) == '11111111'
|
assert get_account_number(arn) == '11111111'
|
||||||
|
|
||||||
|
|
||||||
def test_mint_certificate(issuer_plugin, authority, logged_in_admin):
|
def test_mint_certificate(issuer_plugin, authority):
|
||||||
from lemur.certificates.service import mint
|
from lemur.certificates.service import mint
|
||||||
cert_body, private_key, chain = mint(authority=authority, csr=CSR_STR)
|
cert_body, private_key, chain = mint(authority=authority, csr=CSR_STR)
|
||||||
assert cert_body == INTERNAL_VALID_LONG_STR, INTERNAL_VALID_SAN_STR
|
assert cert_body == INTERNAL_VALID_LONG_STR, INTERNAL_VALID_SAN_STR
|
||||||
|
@ -372,7 +372,7 @@ def test_create_certificate(issuer_plugin, authority, user):
|
||||||
assert cert.name == 'ACustomName1'
|
assert cert.name == 'ACustomName1'
|
||||||
|
|
||||||
|
|
||||||
def test_reissue_certificate(issuer_plugin, authority, certificate, logged_in_admin):
|
def test_reissue_certificate(issuer_plugin, authority, certificate):
|
||||||
from lemur.certificates.service import reissue_certificate
|
from lemur.certificates.service import reissue_certificate
|
||||||
new_cert = reissue_certificate(certificate)
|
new_cert = reissue_certificate(certificate)
|
||||||
assert new_cert
|
assert new_cert
|
||||||
|
|
|
@ -3,6 +3,8 @@ from freezegun import freeze_time
|
||||||
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from moto import mock_ses
|
||||||
|
|
||||||
|
|
||||||
def test_needs_notification(app, certificate, notification):
|
def test_needs_notification(app, certificate, notification):
|
||||||
from lemur.notifications.messaging import needs_notification
|
from lemur.notifications.messaging import needs_notification
|
||||||
|
@ -21,11 +23,24 @@ def test_needs_notification(app, certificate, notification):
|
||||||
assert needs_notification(certificate)
|
assert needs_notification(certificate)
|
||||||
|
|
||||||
|
|
||||||
@pytest.skip
|
@mock_ses
|
||||||
def test_send_expiration_notification():
|
def test_send_expiration_notification(certificate, notification, notification_plugin):
|
||||||
assert False
|
from lemur.notifications.messaging import send_expiration_notifications
|
||||||
|
notification.options = [{'name': 'interval', 'value': 10}, {'name': 'unit', 'value': 'days'}]
|
||||||
|
certificate.notifications.append(notification)
|
||||||
|
delta = certificate.not_after - timedelta(days=10)
|
||||||
|
|
||||||
|
with freeze_time(delta.datetime):
|
||||||
|
sent = send_expiration_notifications()
|
||||||
|
assert sent == 1
|
||||||
|
|
||||||
|
certificate.notify = False
|
||||||
|
|
||||||
|
sent = send_expiration_notifications()
|
||||||
|
assert sent == 0
|
||||||
|
|
||||||
|
|
||||||
@pytest.skip
|
@mock_ses
|
||||||
def test_send_rotation_notification():
|
def test_send_rotation_notification(notification_plugin, certificate):
|
||||||
assert False
|
from lemur.notifications.messaging import send_rotation_notification
|
||||||
|
send_rotation_notification(certificate, notification_plugin=notification_plugin)
|
||||||
|
|
Loading…
Reference in New Issue