Merge pull request #25 from kevgliss/smtp

Adding support for SMTP emails
This commit is contained in:
kevgliss 2015-07-23 16:28:54 -07:00
commit 1191fbe6c2
9 changed files with 105 additions and 80 deletions

View File

@ -63,26 +63,6 @@ Basic Configuration
SQLALCHEMY_DATABASE_URI = 'postgresql://<user>:<password>@<hostname>:5432/lemur'
.. data:: LEMUR_MAIL
:noindex:
Lemur mail service
::
LEMUR_MAIL = 'lemur.example.com'
.. data:: LEMUR_SECURITY_TEAM_EMAIL
:noindex:
This is an email or list of emails that should be notified when a certificate is expiring. It is also the contact email address for any discovered certificate.
::
LEMUR_SECURITY_TEAM_EMAIL = ['security@example.com']
.. data:: LEMUR_RESTRICTED_DOMAINS
:noindex:
@ -122,6 +102,57 @@ Basic Configuration
LEMUR_ENCRYPTION_KEY = 'supersupersecret'
Notification Options
--------------------
Lemur currently has very basic support for notifications. Notifications are sent to the certificate creator, owner and
security team as specified by the `SECURITY_TEAM_EMAIL` configuration parameter.
The template for all of these notifications lives under lemur/template/event.html and can be easily modified to fit your
needs.
Certificates marked as in-active will **not** be notified of upcoming expiration. This enables a user to essentially
silence the expiration. If a certificate is active and is expiring the above will be notified at 30, 15, 5, 2 days
respectively.
Lemur supports sending certification expiration notifications through SES and SMTP.
.. data:: LEMUR_EMAIL_SENDER
:noindex:
Specifies which service will be delivering notification emails. Valid values are `SMTP` or `SES`
.. note::
If using STMP as your provider you will need to define additional configuration options as specified by Flask-Mail.
See: `Flask-Mail <https://pythonhosted.org/Flask-Mail>`_
If you are using SES the email specified by the `LEMUR_MAIL` configuration will need to be verified by AWS before
you can send any mail. See: `Verifying Email Address in Amazon SES <http://docs.aws.amazon.com/ses/latest/DeveloperGuide/verify-email-addresses.html>`_
.. data:: LEMUR_MAIL
:noindex:
Lemur sender's email
::
LEMUR_MAIL = 'lemur.example.com'
.. data:: LEMUR_SECURITY_TEAM_EMAIL
:noindex:
This is an email or list of emails that should be notified when a certificate is expiring. It is also the contact email address for any discovered certificate.
::
LEMUR_SECURITY_TEAM_EMAIL = ['security@example.com']
.. data::
Authority Options
-----------------
@ -191,19 +222,6 @@ If you are not using PING you do not need to configure any of these options
PING_JWKS_URL = "https://<yourpingserver>/pf/JWKS"
Notifications
=============
Lemur currently has very basic support for notifications. Notifications are send to the certificate creator, owner and
security team as specified by the `SECURITY_TEAM_EMAIL` configuration parameter.
The template for all of these notifications lives under lemur/template/event.html and can be easily modified to fit your
needs.
Certificates marked as in-active will **not** be notified of upcoming expiration. This enables a user to essentially
silence the expiration. If a certificate is active and is expiring the above will be notified at 30, 15, 5, 2 days
respectively. Lemur will not attempt to notify about certificate that have already expired.
AWS Configuration
=================

View File

@ -1,28 +0,0 @@
"""
.. module: lemur.common.services.aws
: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>
"""
import boto.ses
from flask import current_app
from lemur.templates.config import env
def send(subject, data, email_type, recipients):
"""
Configures all Lemur email messaging
:param subject:
:param data:
:param email_type:
:param recipients:
"""
conn = boto.connect_ses()
# jinja template depending on type
template = env.get_template('{}.html'.format(email_type))
body = template.render(**data)
conn.send_email(current_app.config.get("LEMUR_EMAIL"), subject, body, recipients, format='html')

View File

@ -14,3 +14,6 @@ bcrypt = Bcrypt()
from flask.ext.principal import Principal
principal = Principal()
from flask_mail import Mail
smtp_mail = Mail()

View File

@ -19,7 +19,7 @@ from logging.handlers import RotatingFileHandler
from flask import Flask
from lemur.common.health import mod as health
from lemur.extensions import db, migrate, principal
from lemur.extensions import db, migrate, principal, smtp_mail
DEFAULT_BLUEPRINTS = (
@ -111,6 +111,7 @@ def configure_extensions(app):
db.init_app(app)
migrate.init_app(app, db)
principal.init_app(app)
smtp_mail.init_app(app)
def configure_blueprints(app, blueprints):

View File

@ -72,8 +72,6 @@ LEMUR_RESTRICTED_DOMAINS = []
# Mail Server
# Lemur currently only supports SES for sending email, this address
# needs to be verified
LEMUR_EMAIL = ''
LEMUR_SECURITY_TEAM_EMAIL = []
@ -92,34 +90,32 @@ SQLALCHEMY_DATABASE_URI = 'postgresql://lemur:lemur@localhost:5432/lemur'
# AWS
# Lemur will need STS assume role access to every destination you want to monitor
#AWS_ACCOUNT_MAPPINGS = {{
# AWS_ACCOUNT_MAPPINGS = {{
# '1111111111': 'myawsacount'
#}}
# }}
## This is useful if you know you only want to monitor one destination
#AWS_REGIONS = ['us-east-1']
#LEMUR_INSTANCE_PROFILE = 'Lemur'
#############
## Issuers ##
#############
# Issuers
# These will be dependent on which 3rd party that Lemur is
# configured to use.
#CLOUDCA_URL = ''
#CLOUDCA_PEM_PATH = ''
#CLOUDCA_BUNDLE = ''
# CLOUDCA_URL = ''
# CLOUDCA_PEM_PATH = ''
# CLOUDCA_BUNDLE = ''
# number of years to issue if not specified
#CLOUDCA_DEFAULT_VALIDITY = 2
# CLOUDCA_DEFAULT_VALIDITY = 2
#VERISIGN_URL = ''
#VERISIGN_PEM_PATH = ''
#VERISIGN_FIRST_NAME = ''
#VERISIGN_LAST_NAME = ''
#VERSIGN_EMAIL = ''
# VERISIGN_URL = ''
# VERISIGN_PEM_PATH = ''
# VERISIGN_FIRST_NAME = ''
# VERISIGN_LAST_NAME = ''
# VERSIGN_EMAIL = ''
"""

View File

@ -12,13 +12,19 @@ import ssl
import socket
import arrow
import boto.ses
from flask import current_app
from flask_mail import Message
from lemur import database
from lemur.common.services.aws import ses
from lemur.certificates.models import Certificate
from lemur.domains.models import Domain
from lemur.templates.config import env
from lemur.extensions import smtp_mail
NOTIFICATION_INTERVALS = [30, 15, 5, 2]
@ -84,7 +90,7 @@ def send_expiration_notifications():
for messages, recipients in roll_ups:
notifications += 1
ses.send("Certificate Expiration", dict(messages=messages), 'event', recipients)
send("Certificate Expiration", dict(messages=messages), 'event', recipients)
print notifications
current_app.logger.info("Lemur has sent {0} certification notifications".format(notifications))
@ -182,3 +188,31 @@ def _create_roll_ups(messages):
else:
roll_ups.append(([message_data], recipients))
return roll_ups
def send(subject, data, email_type, recipients):
"""
Configures all Lemur email messaging
:param subject:
:param data:
:param email_type:
:param recipients:
"""
# jinja template depending on type
template = env.get_template('{}.html'.format(email_type))
body = template.render(**data)
s_type = current_app.config.get("LEMUR_EMAIL_SENDER").lower()
if s_type == 'ses':
conn = boto.connect_ses()
conn.send_email(current_app.config.get("LEMUR_EMAIL"), subject, body, recipients, format='html')
elif s_type == 'smtp':
msg = Message(subject, recipients=recipients)
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!")

View File

@ -29,6 +29,7 @@ install_requires = [
'Flask-Migrate>=1.4.0',
'Flask-Bcrypt>=0.6.2',
'Flask-Principal>=0.4.0',
'Flask-Mail==0.9.1',
'SQLAlchemy-Utils>=0.30.11',
'BeautifulSoup4',
'requests>=2.7.0',