""" EmailAgent This agent reads the ResourceStatusCache table of ResourceStatusDB for sending emails with aggregated information about state changes, and then clears it. .. literalinclude:: ../ConfigTemplate.cfg :start-after: ##BEGIN EmailAgent :end-before: ##END :dedent: 2 :caption: EmailAgent options """ from __future__ import absolute_import from __future__ import division from __future__ import print_function from DIRAC import gConfig, S_OK, S_ERROR from DIRAC.Core.Base.AgentModule import AgentModule from DIRAC.ResourceStatusSystem.Client.ResourceStatusClient import ResourceStatusClient from DIRAC.ResourceStatusSystem.Utilities import RssConfiguration from DIRAC.Interfaces.API.DiracAdmin import DiracAdmin __RCSID__ = "c59810311 (2021-10-01 10:44:25 +0200) Chris Burr " AGENT_NAME = "ResourceStatus/EmailAgent" class EmailAgent(AgentModule): def __init__(self, *args, **kwargs): AgentModule.__init__(self, *args, **kwargs) self.diracAdmin = None self.default_value = None self.rsClient = ResourceStatusClient() def initialize(self, *args, **kwargs): """EmailAgent initialization""" self.diracAdmin = DiracAdmin() return S_OK() @staticmethod def _groupBySiteName(result): """ Group results by SiteName """ siteNameCol = result["Columns"].index("SiteName") resultValue = result["Value"] siteNameDict = {} for row in resultValue: if row[siteNameCol] not in siteNameDict: siteNameDict[row[siteNameCol]] = [row] else: siteNameDict[row[siteNameCol]].append(row) return siteNameDict def execute(self): result = self.rsClient.select("ResourceStatusCache") if not result["OK"]: return S_ERROR() columnNames = result["Columns"] result = self._groupBySiteName(result) for site, records in result.items(): email = "" html_body = "" html_elements = "" if gConfig.getValue("/DIRAC/Setup"): setup = "(" + gConfig.getValue("/DIRAC/Setup") + ")\n\n" else: setup = "" html_header = """\

{setup}

""".format( setup=setup ) for row in records: statusType = row[columnNames.index("StatusType")] resourceName = row[columnNames.index("ResourceName")] status = row[columnNames.index("Status")] time = row[columnNames.index("Time")] previousStatus = row[columnNames.index("PreviousStatus")] html_elements += ( "" + "" + statusType + "" + "" + resourceName + "" + "" + status + "" + "" + str(time) + "" + "" + previousStatus + "" + "" ) html_body = """\ {html_elements}
Status Type Resource Name Status Time Previous Status
""".format( html_elements=html_elements ) email = html_header + html_body subject = "RSS actions taken for " + str(site) + "\n" self._sendMail(subject, email, html=True) self.rsClient.delete("ResourceStatusCache") return S_OK() def _sendMail(self, subject, body, html=False): userEmails = self._getUserEmails() if not userEmails["OK"]: return userEmails # User email address used to send the emails from. fromAddress = RssConfiguration.RssConfiguration().getConfigFromAddress() for user in userEmails["Value"]: # FIXME: should not I get the info from the RSS User cache ? resEmail = self.diracAdmin.sendMail(user, subject, body, fromAddress=fromAddress, html=html) if not resEmail["OK"]: return S_ERROR('Cannot send email to user "%s"' % user) return S_OK() def _getUserEmails(self): configResult = RssConfiguration.getnotificationGroups() if not configResult["OK"]: return configResult try: notificationGroups = configResult["Value"]["notificationGroups"] except KeyError: return S_ERROR("%s/notificationGroups not found") notifications = RssConfiguration.getNotifications() if not notifications["OK"]: return notifications notifications = notifications["Value"] userEmails = [] for notificationGroupName in notificationGroups: try: userEmails.extend(notifications[notificationGroupName]["users"]) except KeyError: self.log.error("%s not present" % notificationGroupName) return S_OK(userEmails)