Loading Dockerfile +0 −5 Original line number Diff line number Diff line Loading @@ -9,9 +9,4 @@ COPY src/ tmp/src RUN set -eux && pip install --upgrade pip && \ cd /tmp/src/ && pip install -e . && \ pip install pytest pytest-cov COPY ./test/test.py /test/test.py CMD ['sh', 'tail', '-f', '/dev/null'] docker-compose.test.yaml +3 −3 Original line number Diff line number Diff line Loading @@ -7,10 +7,10 @@ services: - ./src/:/tmp/src - ./test/:/test/ env_file: #- ./envfile_mssql - ./envfile - ./test_envfile #command: ["sh", "-c", "pytest --cov=common /test/test.py"] command: ["sh", "-c", "test-db-conn && pytest -v --cov=common /test/test.py --cov-report term-missing"] #command: ["sh", "-c", "test-db-conn && pytest -v --cov=common /test/test.py"] command: ["python3", "/test/test.py"] depends_on: - postgres Loading docker-compose.yaml +0 −1 Original line number Diff line number Diff line Loading @@ -21,4 +21,3 @@ services: volumes: - ./sql/create_tables.sql:/docker-entrypoint-initdb.d/create_tables.sql - ./sql/fill_tables.sql:/docker-entrypoint-initdb.d/fill_tables.sql src/common/mail.py +57 −5 Original line number Diff line number Diff line #!/usr/bin/env python3 # -*- coding: utf-8 -*- import smtplib import os import ssl from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.application import MIMEApplication from common.env import check_environment as ce from common.logz import create_logger def send_email(subject, text): def send_email(subject, text, files=None): """ Send email to the EMAIL_RECIPIENTS env variable with the given subject and message body from the EMAIL_SENDER address. Email debug level is controlled with the EMAIL_DEBUG_LEVEL environmental variable and Loading @@ -18,8 +21,12 @@ def send_email(subject, text): :return: None """ logger = create_logger() from_address = ce('EMAIL_SENDER') smtp_address = ce('SMTP_ADDRESS', 'smtp.ornl.gov') relay_address = ce('RELAY_ADDRESS') relay_port = ce('RELAY_PORT') relay_password = ce('RELAY_PASSWORD') smtp_port = ce('SMTP_PORT', 25) if from_address is None: logger.critical('Unable to send email as no EMAIL_SENDER set') Loading @@ -36,13 +43,58 @@ def send_email(subject, text): msg['To'] = to_address msg['Subject'] = subject msg.attach(MIMEText(text, 'plain')) # if attachment files have been passed.. if isinstance(files, list) and len(files) > 0: for f in files: if os.path.isfile(f): with open(f, 'rb') as att_file: part = MIMEApplication(att_file.read()) part['Content-Disposition'] = ('attachment; filename=' f'"{os.path.basename(f)}"') msg.attach(part) else: logger.error(f'Failed to attach file {f}. {f} is not a file.') elif isinstance(files, str) and len(files) > 0: if os.path.isfile(files): with open(files, 'rb') as att_file: part = MIMEApplication(att_file.read()) part['Content-Disposition'] = ('attachment; filename=' f'"{os.path.basename(files)}"') msg.attach(part) else: logger.error(f'Failed to attach file {files}. {files} is not a ' 'file.') else: logger.error(f'Failed to attach files "{files}". Please ensure that ' '"files" is passed as type "list"') logger.info(f'Sending email to {to_address} from {from_address}') try: # try: if all(var is None for var in [relay_address, relay_port, relay_password]): with smtplib.SMTP(smtp_address, smtp_port) as server: server.set_debuglevel(ce('EMAIL_DEBUG_LEVEL', 0)) server.send_message(msg) server.quit() logger.info(f'Email successfully sent to {to_address}.') except smtplib.SMTPException as error: logger.error(f'Error sending email: {error}') elif all(var is not None for var in [relay_address, relay_port, relay_address]): # allow ssl connection context = ssl.create_default_context() with smtplib.SMTP(relay_address, relay_port) as conn: conn.ehlo() conn.starttls(context=context) conn.login(from_address, relay_password) conn.send_message(msg) conn.quit() logger.info(f'Email successfully sent to {to_address}.') else: logger.error("Misconfigured environment variables detected. " + "Please specify either all environment variables " + "for relay addresses or none of them. Relay " + "environment variables: 'RELAY_ADDRESS', " + "'RELAY_PORT', 'RELAY_PASSWORD'") # except smtplib.SMTPException as error: # logger.error(f'Error sending email: {error}') return None test/test.py +28 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ from common.mixins.postgres import PostgresMixin from common.mixins.mssql import MSSQLMixin from common.mixins.postgres_logger import PostgresLoggerMixin from common.logz import create_logger from common.mail import send_email class DBPG(Database, PostgresMixin): Loading Loading @@ -224,5 +225,32 @@ class LogzTestCase(unittest.TestCase): # test empty list: plm.write_log_collection_to_database() class MailTestCase(unittest.TestCase): """MailTestCase.""" def test_send_email(self): """Test to make sure that then send_mail function can actually send mail""" send_email("TEST SUBJECT", "THIS IS A TEST MESSAGE") def test_send_email_attachment(self): """Test to make sure that we can send attachments..""" ATTACHMENT_PATHS = ["/test/test_attachments/test_attachment.txt", "/test/test_attachments/test_attachment2.txt"] ATTACHMENT_PATHS_W_BAD_FILE = [ "/test/test_attachments/test_attachment.txt", "/this/is/not/a/real/file/path.txt"] send_email( "TEST SUBJECT WITH ATTACHMENT", "THIS IS A TEST MESSAGE", files=[ATTACHMENT_PATHS[0]] ) send_email("TEST SUBJECT MULTI-ATTACHMENTS", "TEST MESSAGE", files=ATTACHMENT_PATHS) send_email("TEST SUBJECT WITH BAD PATH", "TEST MESSAGE", files=ATTACHMENT_PATHS_W_BAD_FILE) send_email("TEST SUBJECT WITH STRING FILE PATH", "TEST MESSAGE", files=ATTACHMENT_PATHS[0]) if __name__ == "__main__": unittest.main(verbosity=2) Loading
Dockerfile +0 −5 Original line number Diff line number Diff line Loading @@ -9,9 +9,4 @@ COPY src/ tmp/src RUN set -eux && pip install --upgrade pip && \ cd /tmp/src/ && pip install -e . && \ pip install pytest pytest-cov COPY ./test/test.py /test/test.py CMD ['sh', 'tail', '-f', '/dev/null']
docker-compose.test.yaml +3 −3 Original line number Diff line number Diff line Loading @@ -7,10 +7,10 @@ services: - ./src/:/tmp/src - ./test/:/test/ env_file: #- ./envfile_mssql - ./envfile - ./test_envfile #command: ["sh", "-c", "pytest --cov=common /test/test.py"] command: ["sh", "-c", "test-db-conn && pytest -v --cov=common /test/test.py --cov-report term-missing"] #command: ["sh", "-c", "test-db-conn && pytest -v --cov=common /test/test.py"] command: ["python3", "/test/test.py"] depends_on: - postgres Loading
docker-compose.yaml +0 −1 Original line number Diff line number Diff line Loading @@ -21,4 +21,3 @@ services: volumes: - ./sql/create_tables.sql:/docker-entrypoint-initdb.d/create_tables.sql - ./sql/fill_tables.sql:/docker-entrypoint-initdb.d/fill_tables.sql
src/common/mail.py +57 −5 Original line number Diff line number Diff line #!/usr/bin/env python3 # -*- coding: utf-8 -*- import smtplib import os import ssl from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.application import MIMEApplication from common.env import check_environment as ce from common.logz import create_logger def send_email(subject, text): def send_email(subject, text, files=None): """ Send email to the EMAIL_RECIPIENTS env variable with the given subject and message body from the EMAIL_SENDER address. Email debug level is controlled with the EMAIL_DEBUG_LEVEL environmental variable and Loading @@ -18,8 +21,12 @@ def send_email(subject, text): :return: None """ logger = create_logger() from_address = ce('EMAIL_SENDER') smtp_address = ce('SMTP_ADDRESS', 'smtp.ornl.gov') relay_address = ce('RELAY_ADDRESS') relay_port = ce('RELAY_PORT') relay_password = ce('RELAY_PASSWORD') smtp_port = ce('SMTP_PORT', 25) if from_address is None: logger.critical('Unable to send email as no EMAIL_SENDER set') Loading @@ -36,13 +43,58 @@ def send_email(subject, text): msg['To'] = to_address msg['Subject'] = subject msg.attach(MIMEText(text, 'plain')) # if attachment files have been passed.. if isinstance(files, list) and len(files) > 0: for f in files: if os.path.isfile(f): with open(f, 'rb') as att_file: part = MIMEApplication(att_file.read()) part['Content-Disposition'] = ('attachment; filename=' f'"{os.path.basename(f)}"') msg.attach(part) else: logger.error(f'Failed to attach file {f}. {f} is not a file.') elif isinstance(files, str) and len(files) > 0: if os.path.isfile(files): with open(files, 'rb') as att_file: part = MIMEApplication(att_file.read()) part['Content-Disposition'] = ('attachment; filename=' f'"{os.path.basename(files)}"') msg.attach(part) else: logger.error(f'Failed to attach file {files}. {files} is not a ' 'file.') else: logger.error(f'Failed to attach files "{files}". Please ensure that ' '"files" is passed as type "list"') logger.info(f'Sending email to {to_address} from {from_address}') try: # try: if all(var is None for var in [relay_address, relay_port, relay_password]): with smtplib.SMTP(smtp_address, smtp_port) as server: server.set_debuglevel(ce('EMAIL_DEBUG_LEVEL', 0)) server.send_message(msg) server.quit() logger.info(f'Email successfully sent to {to_address}.') except smtplib.SMTPException as error: logger.error(f'Error sending email: {error}') elif all(var is not None for var in [relay_address, relay_port, relay_address]): # allow ssl connection context = ssl.create_default_context() with smtplib.SMTP(relay_address, relay_port) as conn: conn.ehlo() conn.starttls(context=context) conn.login(from_address, relay_password) conn.send_message(msg) conn.quit() logger.info(f'Email successfully sent to {to_address}.') else: logger.error("Misconfigured environment variables detected. " + "Please specify either all environment variables " + "for relay addresses or none of them. Relay " + "environment variables: 'RELAY_ADDRESS', " + "'RELAY_PORT', 'RELAY_PASSWORD'") # except smtplib.SMTPException as error: # logger.error(f'Error sending email: {error}') return None
test/test.py +28 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ from common.mixins.postgres import PostgresMixin from common.mixins.mssql import MSSQLMixin from common.mixins.postgres_logger import PostgresLoggerMixin from common.logz import create_logger from common.mail import send_email class DBPG(Database, PostgresMixin): Loading Loading @@ -224,5 +225,32 @@ class LogzTestCase(unittest.TestCase): # test empty list: plm.write_log_collection_to_database() class MailTestCase(unittest.TestCase): """MailTestCase.""" def test_send_email(self): """Test to make sure that then send_mail function can actually send mail""" send_email("TEST SUBJECT", "THIS IS A TEST MESSAGE") def test_send_email_attachment(self): """Test to make sure that we can send attachments..""" ATTACHMENT_PATHS = ["/test/test_attachments/test_attachment.txt", "/test/test_attachments/test_attachment2.txt"] ATTACHMENT_PATHS_W_BAD_FILE = [ "/test/test_attachments/test_attachment.txt", "/this/is/not/a/real/file/path.txt"] send_email( "TEST SUBJECT WITH ATTACHMENT", "THIS IS A TEST MESSAGE", files=[ATTACHMENT_PATHS[0]] ) send_email("TEST SUBJECT MULTI-ATTACHMENTS", "TEST MESSAGE", files=ATTACHMENT_PATHS) send_email("TEST SUBJECT WITH BAD PATH", "TEST MESSAGE", files=ATTACHMENT_PATHS_W_BAD_FILE) send_email("TEST SUBJECT WITH STRING FILE PATH", "TEST MESSAGE", files=ATTACHMENT_PATHS[0]) if __name__ == "__main__": unittest.main(verbosity=2)