Certificate rotation enhancements (#570)

This commit is contained in:
kevgliss
2016-12-07 16:24:59 -08:00
committed by GitHub
parent 9adc5ad59e
commit fc205713c8
19 changed files with 607 additions and 598 deletions

View File

@ -1,5 +1,5 @@
"""
.. module: lemur.plugins.lemur_aws.aws
.. module: lemur.plugins.lemur_email.plugin
:platform: Unix
:copyright: (c) 2015 by Netflix Inc., see AUTHORS for more
:license: Apache, see LICENSE for more details.
@ -11,14 +11,53 @@ from flask import current_app
from flask_mail import Message
from lemur.extensions import smtp_mail
from lemur.exceptions import InvalidConfiguration
from lemur.plugins.bases import ExpirationNotificationPlugin
from lemur.plugins import lemur_email as email
from lemur.plugins.lemur_email.templates.config import env
def render_html(template_name, message):
"""
Renders the html for our email notification.
:param template_name:
:param message:
:return:
"""
template = env.get_template('{}.html'.format(template_name))
return template.render(dict(messages=message, hostname=current_app.config.get('LEMUR_HOSTNAME')))
def send_via_ses(subject, body, targets):
"""
Attempts to deliver email notification via SES service.
:param subject:
:param body:
:param targets:
:return:
"""
msg = Message(subject, recipients=targets)
msg.body = "" # kinda a weird api for sending html emails
msg.html = body
smtp_mail.send(msg)
def send_via_smtp(subject, body, targets):
"""
Attempts to deliver email notification via SMTP.
:param subject:
:param body:
:param targets:
:return:
"""
conn = boto.connect_ses()
conn.send_email(current_app.config.get("LEMUR_EMAIL"), subject, body, targets, format='html')
class EmailNotificationPlugin(ExpirationNotificationPlugin):
title = 'Email'
slug = 'email-notification'
@ -38,33 +77,23 @@ class EmailNotificationPlugin(ExpirationNotificationPlugin):
},
]
def __init__(self, *args, **kwargs):
"""Initialize the plugin with the appropriate details."""
sender = current_app.config.get('LEMUR_EMAIL_SENDER', 'ses').lower()
if sender not in ['ses', 'smtp']:
raise InvalidConfiguration('Email sender type {0} is not recognized.')
@staticmethod
def send(event_type, message, targets, options, **kwargs):
"""
Configures all Lemur email messaging
def send(template_name, message, targets, **kwargs):
subject = 'Lemur: Expiration Notification'
:param event_type:
:param options:
"""
subject = 'Notification: Lemur'
if event_type == 'expiration':
subject = 'Notification: SSL Certificate Expiration '
# jinja template depending on type
template = env.get_template('{}.html'.format(event_type))
body = template.render(dict(messages=message, hostname=current_app.config.get('LEMUR_HOSTNAME')))
body = render_html(template_name, message)
s_type = current_app.config.get("LEMUR_EMAIL_SENDER", 'ses').lower()
if s_type == 'ses':
conn = boto.connect_ses()
conn.send_email(current_app.config.get("LEMUR_EMAIL"), subject, body, targets, format='html')
send_via_ses(subject, body, targets)
elif s_type == 'smtp':
msg = Message(subject, recipients=targets)
msg.body = "" # kinda a weird api for sending html emails
msg.html = body
smtp_mail.send(msg)
else:
current_app.logger.error("No mail carrier specified, notification emails were not able to be sent!")
send_via_smtp(subject, body, targets)

View File

@ -34,7 +34,7 @@
<tr height="16"></tr>
<tr>
<td>
<table bgcolor="#F44336" width="100%" border="0" cellspacing="0" cellpadding="0"
<table bgcolor="#3681E4" width="100%" border="0" cellspacing="0" cellpadding="0"
style="min-width:332px;max-width:600px;border:1px solid #e0e0e0;border-bottom:0;border-top-left-radius:3px;border-top-right-radius:3px">
<tbody>
<tr>
@ -43,7 +43,7 @@
<tr>
<td width="32px"></td>
<td style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:24px;color:#ffffff;line-height:1.25">
Your certificate(s) are being rotated!
Your certificate(s) have been rotated!
</td>
<td width="32px"></td>
</tr>
@ -56,7 +56,7 @@
</tr>
<tr>
<td>
<table bgcolor="#3681E4" width="100%" border="0" cellspacing="0" cellpadding="0"
<table width="100%" border="0" cellspacing="0" cellpadding="0"
style="min-width:332px;max-width:600px;border:1px solid #f0f0f0;border-bottom:1px solid #c0c0c0;border-top:0;border-bottom-left-radius:3px;border-bottom-right-radius:3px">
<tbody>
<tr height="16px">
@ -71,11 +71,51 @@
<tr>
<td style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:13px;color:#202020;line-height:1.5">
Hi,
<br>This is a Lemur certificate rotation notice. Your certificate has been re-issued and re-provisioned.
</td>
</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>
<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 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">{{ message.name }}</span>
<br>
<span style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:13px;color:#727272">
{{ message.endpoints | length }} Endpoints
<br>{{ message.owner }}
<br>{{ message.not_after | time }}
<a href="https://{{ hostname }}/#/certificates/{{ message.name }}" target="_blank">Details</a>
</span>
</td>
</tr>
{% if not loop.last %}
<tr valign="middle">
<td width="32px" height="24px"></td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</td>
</tr>
<tr>
<td style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:20px;color:#202020;line-height:1.5">
Impacted Endpoints:
</td>
</tr>
<tr>
<td style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:13px;color:#202020;line-height:1.5">
<br>This is a Lemur certificate rotation notice. This a purely informational notice. The following certificates will be rotated on any associated endpoints.
<table border="0" cellspacing="0" cellpadding="0"
style="margin-top:48px;margin-bottom:48px">
<tbody>

21
lemur/plugins/utils.py Normal file
View File

@ -0,0 +1,21 @@
"""
.. module: lemur.plugins.utils
:platform: Unix
:copyright: (c) 2015 by Netflix Inc., see AUTHORS for more
:license: Apache, see LICENSE for more details.
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
"""
def get_plugin_option(name, options):
"""
Retrieve option name from options dict.
:param options:
:return:
"""
for o in options:
if o.get('name') == name:
return o['value']