[minor] refactor mail server connection code

- Added `connect_to_mail_server` function to handle mail server connection
- Moved code for connecting to the mail server from `StationQC` class to `connect_to_mail_server`
- Updated references to use `connect_to_mail_server` in `StationQC` class
- Created new function `get_credential` to retrieve credentials from Docker secrets or environment variables
This commit is contained in:
Kasper D. Fischer 2025-03-21 12:36:52 +01:00
parent 43912135e9
commit cf12500ec2
2 changed files with 54 additions and 39 deletions

View File

@ -23,7 +23,8 @@ from obspy.clients.filesystem.sds import Client
from write_utils import get_html_text, get_html_link, get_html_row, html_footer, get_html_header, get_print_title_str, \
init_html_table, finish_html_table, get_mail_html_header, add_html_image
from utils import get_bg_color, get_font_color, modify_stream_for_plot, set_axis_yticks, set_axis_color, plot_axis_thresholds
from utils import get_bg_color, get_font_color, modify_stream_for_plot, set_axis_yticks, set_axis_color, plot_axis_thresholds, \
connect_to_mail_server
try:
import smtplib
@ -738,7 +739,6 @@ class StationQC(object):
if add_addresses:
# create copy of addresses ( [:] ) to prevent changing original, general list with addresses
addresses = addresses[:] + list(add_addresses)
server = mail_params.get('mailserver')
if not sender or not addresses:
logging.info('Mail sender or addresses not (correctly) defined. Return')
return
@ -757,43 +757,10 @@ class StationQC(object):
html_str = self.add_html_mail_body(text)
msg.add_alternative(html_str, subtype='html')
# send message via SMTP server
# set up starttls connection if server is not "localhost"
if server == 'localhost':
# create connection to localhost
s = smtplib.SMTP(server)
else:
user = mail_params.get('user')
# read user from docker secret if it is set to 'DOCKER' or
# read user from environment variable if it is set to 'ENV'
if user == 'DOCKER':
try:
with open('/run/secrets/mail_user', 'r') as f:
user = f.read().strip()
except FileNotFoundError as e:
logging.error('Could not read mail user from docker secret')
logging.error(e)
elif user == 'ENV':
user = os.environ.get(mail_params.get('user_env'))
password = mail_params.get('password')
# read password from docker secret if it is set to 'DOCKER' or
# read password from environment variable if it is set to 'ENV'
if password == 'DOCKER':
try:
with open('/run/secrets/mail_password', 'r') as f:
password = f.read().strip()
except FileNotFoundError as e:
logging.error('Could not read mail password from docker secret')
logging.error(e)
elif password == 'ENV':
password = os.environ.get(mail_params.get('password_env'))
# create SSL connection to server
s = smtplib.SMTP_SSL(server, mail_params.get('port'))
s.login(mail_params.get('user'), mail_params.get('password'))
# send mail and close connection
# connect to server, send mail and close connection
s = connect_to_mail_server(mail_params)
if not s: # if connection failed
return
s.send_message(msg)
s.quit()

View File

@ -5,6 +5,7 @@ import logging
import matplotlib
import numpy as np
import smtplib
from obspy import Stream
@ -279,3 +280,50 @@ def annotate_voltage_states(ax, parameters, pb_key, color='0.75'):
ax.annotate(out_string, (ax.get_xlim()[-1], voltage), color=color, fontsize='xx-small',
horizontalalignment='right')
def get_credential(source, param):
"""
Retrieve a credential from a Docker secret or environment variable.
"""
if source == 'DOCKER':
try:
with open('/run/secrets/'+param.lower(), 'r') as f:
return f.read().strip()
except FileNotFoundError as e:
logging.error(f'Could not read from Docker secret at /run/secrets/{param.lower()}')
logging.error(e)
elif source == 'ENV':
try:
return os.environ.get(param.upper())
except Exception as e:
logging.error(f'Could not read from environment variable {param.upper()}')
logging.error(e)
# return source if no credential was found
return source
def connect_to_mail_server(self, mail_params):
"""
Connect to mail server and return server object.
"""
# get server from parameters
server = mail_params.get('mailserver')
# get auth_type from parameters
auth_type = mail_params.get('auth_type')
# set up connection to mail server
if auth_type == 'None':
s = smtplib.SMTP(server)
else:
# user and password from parameters, docker secret or environment variable
user = get_credential(mail_params.get('user'), 'mail_user')
password = get_credential(mail_params.get('password'), 'mail_password')
# create secure connection to server
if auth_type == 'SSL':
s = smtplib.SMTP_SSL(server, mail_params.get('port'))
elif auth_type == 'TLS':
s = smtplib.SMTP(server, mail_params.get('port'))
s.starttls()
else:
logging.error('Unknown authentication type. Mails can not be sent')
return
s.login(mail_params.get('user'), mail_params.get('password'))
return s