diff --git a/gso/services/mailer.py b/gso/services/mailer.py new file mode 100644 index 0000000000000000000000000000000000000000..be7fd2b1c9c8a6ddb142ccf65c63c761d08fb1d4 --- /dev/null +++ b/gso/services/mailer.py @@ -0,0 +1,26 @@ +"""The mailer service sends notification emails, as part of workflows that require interaction with external parties.""" + +import smtplib +from email.message import EmailMessage + +from gso.settings import load_oss_params + + +def send_mail(recipient, subject, body) -> None: + """Send an email message to the given address. + + :param recipient: The destination address. + :param subject: The email subject. + :param body: The contents of the email message. + """ + email_params = load_oss_params().EMAIL + msg = EmailMessage() + msg["From"] = email_params.from_address + msg["To"] = recipient + msg["Subject"] = subject + msg.set_content(body) + + with smtplib.SMTP(email_params.smtp_host, email_params.smtp_port) as s: + if email_params.smtp_username or email_params.smtp_password: + s.login(email_params.smtp_username, email_params.smtp_password) + s.send_message(msg) diff --git a/gso/settings.py b/gso/settings.py index ca0da591c00e829585db55c5a68731b3c44aac90..6c7fc8ef37547d00f9cb86e139e173df93132d39 100644 --- a/gso/settings.py +++ b/gso/settings.py @@ -152,6 +152,17 @@ class NetBoxParams(BaseSettings): api: str +class EmailParams(BaseSettings): + """Parameters for the email service.""" + + # TODO: Use more strict types after we've migrated to Pydantic 2.x + from_address: str + smtp_host: str + smtp_port: int + smtp_username: str | None = "" + smtp_password: str | None = "" + + class OSSParams(BaseSettings): """The set of parameters required for running :term:`GSO`.""" @@ -162,6 +173,7 @@ class OSSParams(BaseSettings): PROVISIONING_PROXY: ProvisioningProxyParams CELERY: CeleryParams THIRD_PARTY_API_KEYS: dict[str, str] + EMAIL: EmailParams def load_oss_params() -> OSSParams: