From 819178d63b48cd06b47c8780dabe8b682ae51894 Mon Sep 17 00:00:00 2001 From: Dennis Stam Date: Tue, 8 Oct 2024 08:22:54 +0200 Subject: [PATCH 1/4] Add emailHeaders This optional configuration option, which allows you to add additional headers to the mail --- etc/slurm-mail/slurm-mail.conf | 1 + src/slurmmail/cli.py | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/etc/slurm-mail/slurm-mail.conf b/etc/slurm-mail/slurm-mail.conf index d6e3db7..15f2f74 100644 --- a/etc/slurm-mail/slurm-mail.conf +++ b/etc/slurm-mail/slurm-mail.conf @@ -16,6 +16,7 @@ emailFromUserAddress = root emailFromName = Slurm Admin emailRegEx = \b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b emailSubject = Job $CLUSTER.$JOB_ID: $STATE +# emailHeaders = Precedence: bulk;X-Auto-Response-Suppress: DR, OOF, AutoReply gecosNameField = 0 validateEmail = false datetimeFormat = %d/%m/%Y %H:%M:%S diff --git a/src/slurmmail/cli.py b/src/slurmmail/cli.py index bfb99ca..0cb858e 100644 --- a/src/slurmmail/cli.py +++ b/src/slurmmail/cli.py @@ -83,6 +83,7 @@ def __init__(self) -> None: self.email_from_address: str self.email_from_name: Optional[str] = None self.email_subject: str + self.email_headers: Dict[str, str] = dict() self.mail_regex: str = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b" self.validate_email: Optional[bool] = None self.sacct_exe: pathlib.Path @@ -764,6 +765,12 @@ def __process_spool_file( msg["From"] = options.email_from_address msg["Date"] = email.utils.formatdate(localtime=True) msg["Message-ID"] = email.utils.make_msgid() + + # add optional headers + if options.email_headers: + for header_name, header_value in options.email_headers.items(): + msg[header_name] = header_value + # prefer HTML to plain text, so we add the plain text attachment first (see rfc2046 5.1.4) msg.attach(MIMEText(body_text, "plain")) msg.attach(MIMEText(body_html, "html")) @@ -891,6 +898,11 @@ def send_mail_main(): options.email_from_name = config.get(section, "emailFromName") options.email_subject = config.get(section, "emailSubject") + if config.has_option(section, "emailHeaders"): + email_headers = [ x.strip().split(":", maxsplit=1) for x in config.get(section, "emailHeaders").split(";") ] + for email_header in email_headers: + options.email_headers[email_header[0].strip()] = email_header[1].strip() + if config.has_option(section, "gecosNameField"): Job.GECOS_NAME_FIELD = config.getint(section, "gecosNameField") From 98e2a9edcf2547915c9ef30c6a0c5dfa91fa6087 Mon Sep 17 00:00:00 2001 From: Dennis Stam Date: Tue, 8 Oct 2024 13:45:54 +0200 Subject: [PATCH 2/4] Changed dict() to {} as requested by pylint --- src/slurmmail/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slurmmail/cli.py b/src/slurmmail/cli.py index 0cb858e..5a11587 100644 --- a/src/slurmmail/cli.py +++ b/src/slurmmail/cli.py @@ -83,7 +83,7 @@ def __init__(self) -> None: self.email_from_address: str self.email_from_name: Optional[str] = None self.email_subject: str - self.email_headers: Dict[str, str] = dict() + self.email_headers: Dict[str, str] = {} self.mail_regex: str = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b" self.validate_email: Optional[bool] = None self.sacct_exe: pathlib.Path From 4022f4edbf945992ed23b42724c9884ab2715983 Mon Sep 17 00:00:00 2001 From: Dennis Stam Date: Thu, 17 Oct 2024 09:36:30 +0200 Subject: [PATCH 3/4] Changed double loop and verification of headers - Changed the double for loop, to more readable. - Added an extra check to make sure we do not overrule the already set headers. Print a warning if this is the case and ignore that header --- src/slurmmail/cli.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/slurmmail/cli.py b/src/slurmmail/cli.py index 5a11587..b8485b9 100644 --- a/src/slurmmail/cli.py +++ b/src/slurmmail/cli.py @@ -769,6 +769,12 @@ def __process_spool_file( # add optional headers if options.email_headers: for header_name, header_value in options.email_headers.items(): + if header_name in msg: + logger.warning( + f"Ignoring header_name:{header_name} as header is already set" + ) + continue + msg[header_name] = header_value # prefer HTML to plain text, so we add the plain text attachment first (see rfc2046 5.1.4) @@ -899,9 +905,9 @@ def send_mail_main(): options.email_subject = config.get(section, "emailSubject") if config.has_option(section, "emailHeaders"): - email_headers = [ x.strip().split(":", maxsplit=1) for x in config.get(section, "emailHeaders").split(";") ] - for email_header in email_headers: - options.email_headers[email_header[0].strip()] = email_header[1].strip() + for header in config.get(section, "emailHeaders").split(";"): + header_name, header_value = header.split(":", maxsplit=1) + options.email_headers[header_name.strip()] = header_value.strip() if config.has_option(section, "gecosNameField"): Job.GECOS_NAME_FIELD = config.getint(section, "gecosNameField") From 2c30ee14e012a64ef57f37bbe9673a2acabe31e5 Mon Sep 17 00:00:00 2001 From: Dennis Stam Date: Mon, 21 Oct 2024 08:29:30 +0200 Subject: [PATCH 4/4] Used the correct logging, changed f-string --- src/slurmmail/cli.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/slurmmail/cli.py b/src/slurmmail/cli.py index b8485b9..f515e51 100644 --- a/src/slurmmail/cli.py +++ b/src/slurmmail/cli.py @@ -770,8 +770,9 @@ def __process_spool_file( if options.email_headers: for header_name, header_value in options.email_headers.items(): if header_name in msg: - logger.warning( - f"Ignoring header_name:{header_name} as header is already set" + logging.warning( + "Ignoring header_name %s - header is already set", + header_name ) continue