Merge pull request #25 from kevgliss/smtp
Adding support for SMTP emails
This commit is contained in:
commit
1191fbe6c2
|
@ -63,26 +63,6 @@ Basic Configuration
|
||||||
SQLALCHEMY_DATABASE_URI = 'postgresql://<user>:<password>@<hostname>:5432/lemur'
|
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
|
.. data:: LEMUR_RESTRICTED_DOMAINS
|
||||||
:noindex:
|
:noindex:
|
||||||
|
|
||||||
|
@ -122,6 +102,57 @@ Basic Configuration
|
||||||
LEMUR_ENCRYPTION_KEY = 'supersupersecret'
|
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
|
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"
|
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
|
AWS Configuration
|
||||||
=================
|
=================
|
||||||
|
|
|
@ -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')
|
|
|
@ -14,3 +14,6 @@ bcrypt = Bcrypt()
|
||||||
|
|
||||||
from flask.ext.principal import Principal
|
from flask.ext.principal import Principal
|
||||||
principal = Principal()
|
principal = Principal()
|
||||||
|
|
||||||
|
from flask_mail import Mail
|
||||||
|
smtp_mail = Mail()
|
||||||
|
|
|
@ -19,7 +19,7 @@ from logging.handlers import RotatingFileHandler
|
||||||
|
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from lemur.common.health import mod as health
|
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 = (
|
DEFAULT_BLUEPRINTS = (
|
||||||
|
@ -111,6 +111,7 @@ def configure_extensions(app):
|
||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
migrate.init_app(app, db)
|
migrate.init_app(app, db)
|
||||||
principal.init_app(app)
|
principal.init_app(app)
|
||||||
|
smtp_mail.init_app(app)
|
||||||
|
|
||||||
|
|
||||||
def configure_blueprints(app, blueprints):
|
def configure_blueprints(app, blueprints):
|
||||||
|
|
|
@ -72,8 +72,6 @@ LEMUR_RESTRICTED_DOMAINS = []
|
||||||
|
|
||||||
# Mail Server
|
# Mail Server
|
||||||
|
|
||||||
# Lemur currently only supports SES for sending email, this address
|
|
||||||
# needs to be verified
|
|
||||||
LEMUR_EMAIL = ''
|
LEMUR_EMAIL = ''
|
||||||
LEMUR_SECURITY_TEAM_EMAIL = []
|
LEMUR_SECURITY_TEAM_EMAIL = []
|
||||||
|
|
||||||
|
@ -92,34 +90,32 @@ SQLALCHEMY_DATABASE_URI = 'postgresql://lemur:lemur@localhost:5432/lemur'
|
||||||
# AWS
|
# AWS
|
||||||
|
|
||||||
# Lemur will need STS assume role access to every destination you want to monitor
|
# Lemur will need STS assume role access to every destination you want to monitor
|
||||||
#AWS_ACCOUNT_MAPPINGS = {{
|
# AWS_ACCOUNT_MAPPINGS = {{
|
||||||
# '1111111111': 'myawsacount'
|
# '1111111111': 'myawsacount'
|
||||||
#}}
|
# }}
|
||||||
|
|
||||||
## This is useful if you know you only want to monitor one destination
|
## This is useful if you know you only want to monitor one destination
|
||||||
#AWS_REGIONS = ['us-east-1']
|
#AWS_REGIONS = ['us-east-1']
|
||||||
|
|
||||||
#LEMUR_INSTANCE_PROFILE = 'Lemur'
|
#LEMUR_INSTANCE_PROFILE = 'Lemur'
|
||||||
|
|
||||||
#############
|
# Issuers
|
||||||
## Issuers ##
|
|
||||||
#############
|
|
||||||
|
|
||||||
# These will be dependent on which 3rd party that Lemur is
|
# These will be dependent on which 3rd party that Lemur is
|
||||||
# configured to use.
|
# configured to use.
|
||||||
|
|
||||||
#CLOUDCA_URL = ''
|
# CLOUDCA_URL = ''
|
||||||
#CLOUDCA_PEM_PATH = ''
|
# CLOUDCA_PEM_PATH = ''
|
||||||
#CLOUDCA_BUNDLE = ''
|
# CLOUDCA_BUNDLE = ''
|
||||||
|
|
||||||
# number of years to issue if not specified
|
# number of years to issue if not specified
|
||||||
#CLOUDCA_DEFAULT_VALIDITY = 2
|
# CLOUDCA_DEFAULT_VALIDITY = 2
|
||||||
|
|
||||||
#VERISIGN_URL = ''
|
# VERISIGN_URL = ''
|
||||||
#VERISIGN_PEM_PATH = ''
|
# VERISIGN_PEM_PATH = ''
|
||||||
#VERISIGN_FIRST_NAME = ''
|
# VERISIGN_FIRST_NAME = ''
|
||||||
#VERISIGN_LAST_NAME = ''
|
# VERISIGN_LAST_NAME = ''
|
||||||
#VERSIGN_EMAIL = ''
|
# VERSIGN_EMAIL = ''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,13 +12,19 @@ import ssl
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
import arrow
|
import arrow
|
||||||
|
import boto.ses
|
||||||
|
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
from flask_mail import Message
|
||||||
|
|
||||||
from lemur import database
|
from lemur import database
|
||||||
from lemur.common.services.aws import ses
|
|
||||||
from lemur.certificates.models import Certificate
|
from lemur.certificates.models import Certificate
|
||||||
from lemur.domains.models import Domain
|
from lemur.domains.models import Domain
|
||||||
|
|
||||||
|
from lemur.templates.config import env
|
||||||
|
from lemur.extensions import smtp_mail
|
||||||
|
|
||||||
|
|
||||||
NOTIFICATION_INTERVALS = [30, 15, 5, 2]
|
NOTIFICATION_INTERVALS = [30, 15, 5, 2]
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,7 +90,7 @@ def send_expiration_notifications():
|
||||||
|
|
||||||
for messages, recipients in roll_ups:
|
for messages, recipients in roll_ups:
|
||||||
notifications += 1
|
notifications += 1
|
||||||
ses.send("Certificate Expiration", dict(messages=messages), 'event', recipients)
|
send("Certificate Expiration", dict(messages=messages), 'event', recipients)
|
||||||
|
|
||||||
print notifications
|
print notifications
|
||||||
current_app.logger.info("Lemur has sent {0} certification notifications".format(notifications))
|
current_app.logger.info("Lemur has sent {0} certification notifications".format(notifications))
|
||||||
|
@ -182,3 +188,31 @@ def _create_roll_ups(messages):
|
||||||
else:
|
else:
|
||||||
roll_ups.append(([message_data], recipients))
|
roll_ups.append(([message_data], recipients))
|
||||||
return roll_ups
|
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!")
|
||||||
|
|
1
setup.py
1
setup.py
|
@ -29,6 +29,7 @@ install_requires = [
|
||||||
'Flask-Migrate>=1.4.0',
|
'Flask-Migrate>=1.4.0',
|
||||||
'Flask-Bcrypt>=0.6.2',
|
'Flask-Bcrypt>=0.6.2',
|
||||||
'Flask-Principal>=0.4.0',
|
'Flask-Principal>=0.4.0',
|
||||||
|
'Flask-Mail==0.9.1',
|
||||||
'SQLAlchemy-Utils>=0.30.11',
|
'SQLAlchemy-Utils>=0.30.11',
|
||||||
'BeautifulSoup4',
|
'BeautifulSoup4',
|
||||||
'requests>=2.7.0',
|
'requests>=2.7.0',
|
||||||
|
|
Loading…
Reference in New Issue