def initialize( self ): """ Standard constructor """ try: self.rsDB = ResourceStatusDB() self.rmDB = ResourceManagementDB() self.StorageElementToBeChecked = Queue.Queue() self.StorageElementInCheck = [] self.maxNumberOfThreads = self.am_getOption( 'maxThreadsInPool', 1 ) self.threadPool = ThreadPool( self.maxNumberOfThreads, self.maxNumberOfThreads ) if not self.threadPool: self.log.error( 'Can not create Thread Pool' ) return S_ERROR( 'Can not create Thread Pool' ) self.setup = CS.getSetup()[ 'Value' ] self.VOExtension = CS.getExt() self.StorageElsReadFreqs = CS.getTypedDictRootedAt("CheckingFreqs")[ 'StorageElsReadFreqs' ] self.nc = NotificationClient() self.diracAdmin = DiracAdmin() self.csAPI = CSAPI() for i in xrange( self.maxNumberOfThreads ): self.threadPool.generateJobAndQueueIt( self._executeCheck, args = ( None, ) ) return S_OK() except Exception: errorStr = "StElReadInspectorAgent initialization" gLogger.exception( errorStr ) return S_ERROR( errorStr )
def _getUsersToNotify(self): groups = CS.getTypedDictRootedAtOperations("AssigneeGroups/" + CS.getSetup()).values() concerned_groups = [ g for g in groups if Utils.dictMatch(self.kw["Params"], g) ] return [{ 'Users': g['Users'], 'Notifications': g['Notifications'] } for g in concerned_groups]
def run(self): """ Do actions required to notify users. Mandatory keyword arguments: - Granularity Optional keyword arguments: - SiteType - ServiceType - ResourceType """ # Initializing variables nc = NotificationClient() # raise alarms, right now makes a simple notification if 'Granularity' not in self.kw['Params'].keys(): raise ValueError, "You have to provide a argument Granularity = <desired_granularity>" if self.new_status['Action']: notif = "%s %s is perceived as" % (self.granularity, self.name) notif = notif + " %s. Reason: %s." % (self.new_status['Status'], self.new_status['Reason']) users_to_notify = self._getUsersToNotify() for notif in users_to_notify: for user in notif['Users']: if 'Web' in notif['Notifications']: gLogger.info("Sending web notification to user %s" % user) nc.addNotificationForUser(user, notif) if 'Mail' in notif['Notifications']: gLogger.info("Sending mail notification to user %s" % user) was = self.rsClient.getElementHistory( self.granularity, elementName = self.name, statusType = self.status_type, meta = {"order": "DESC", 'limit' : 1, "columns": ['Status', 'Reason', 'DateEffective']})#[0] if not was[ 'OK' ]: gLogger.error( was[ 'Message' ] ) continue was = was[ 'Value' ][ 0 ] mailMessage = """ ---TESTING--- -------------------------------------------------------------------------------- RSS changed the status of the following resource: Granularity:\t%s Name:\t\t%s New status:\t%s Reason:\t\t%s Was:\t\t%s (%s) since %s Setup:\t\t%s If you think RSS took the wrong decision, please set the status manually: Use: dirac-rss-set-status -g <granularity> -n <element_name> -s <desired_status> [-t status_type] (if you omit the optional last part of the command, all status types are matched.) This notification has been sent according to those parameters: %s """ % (self.granularity, self.name, self.new_status['Status'], self.new_status['Reason'], was[0], was[1], was[2], CS.getSetup(), str(users_to_notify)) # Actually send the mail! resUser = self.rmClient.getUserRegistryCache( user ) if not resUser[ 'OK' ]: gLogger.error( resUser[ 'Message' ] ) continue resUser = resUser[ 'Value' ][ 0 ][ 2 ] nc.sendMail(resUser, '[RSS][%s][%s] %s -> %s' % (self.granularity, self.name, self.new_status['Status'], was[0]), mailMessage) ################################################################################ #EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF
def _getUsersToNotify(self): groups = CS.getTypedDictRootedAtOperations("AssigneeGroups/" + CS.getSetup()).values() concerned_groups = [g for g in groups if Utils.dictMatch(self.kw["Params"], g)] return [{'Users':g['Users'], 'Notifications':g['Notifications']} for g in concerned_groups]
def enforce(self, pdpIn = None, rsDBIn = None, rmDBIn = None, ncIn = None, setupIn = None, daIn = None, csAPIIn = None, knownInfo = None): """ enforce policies, using a PDP (Policy Decision Point), based on self.__granularity (optional) self.__name (optional) self.__status (optional) self.__formerStatus (optional) self.__reason (optional) self.__siteType (optional) self.__serviceType (optional) self.__realBan (optional) self.__user (optional) self.__futurePolicyType (optional) self.__futureGranularity (optional) :params: :attr:`pdpIn`: a custom PDP object (optional) :attr:`rsDBIn`: a custom (statuses) database object (optional) :attr:`rmDBIn`: a custom (management) database object (optional) :attr:`setupIn`: a string with the present setup (optional) :attr:`ncIn`: a custom notification client object (optional) :attr:`daIn`: a custom DiracAdmin object (optional) :attr:`csAPIIn`: a custom CSAPI object (optional) :attr:`knownInfo`: a string of known provided information (optional) """ #PDP if pdpIn is not None: pdp = pdpIn else: # Use standard DIRAC PDP from DIRAC.ResourceStatusSystem.PolicySystem.PDP import PDP pdp = PDP(self.VOExtension, granularity = self.__granularity, name = self.__name, status = self.__status, formerStatus = self.__formerStatus, reason = self.__reason, siteType = self.__siteType, serviceType = self.__serviceType, resourceType = self.__resourceType, useNewRes = self.useNewRes) #DB if rsDBIn is not None: rsDB = rsDBIn else: # Use standard DIRAC DB from DIRAC.ResourceStatusSystem.DB.ResourceStatusDB import ResourceStatusDB rsDB = ResourceStatusDB() if rmDBIn is not None: rmDB = rmDBIn else: # Use standard DIRAC DB from DIRAC.ResourceStatusSystem.DB.ResourceManagementDB import ResourceManagementDB rmDB = ResourceManagementDB() #setup if setupIn is not None: setup = setupIn else: # get present setup setup = CS.getSetup()['Value'] #notification client if ncIn is not None: nc = ncIn else: from DIRAC.FrameworkSystem.Client.NotificationClient import NotificationClient nc = NotificationClient() #DiracAdmin if daIn is not None: da = daIn else: from DIRAC.Interfaces.API.DiracAdmin import DiracAdmin da = DiracAdmin() #CSAPI if csAPIIn is not None: csAPI = csAPIIn else: from DIRAC.ConfigurationSystem.Client.CSAPI import CSAPI csAPI = CSAPI() ################### # policy decision # ################### resDecisions = pdp.takeDecision(knownInfo=knownInfo) if resDecisions != {}: res = resDecisions['PolicyCombinedResult'] policyType = res['PolicyType'] if 'Resource_PolType' in policyType: ResourcePolTypeActions(self.__granularity, self.__name, resDecisions, res, rsDB, rmDB) if 'Alarm_PolType' in policyType: AlarmPolTypeActions(self.__granularity, self.__name, self.__siteType, self.__serviceType, self.__resourceType, res, nc, setup, rsDB) if 'RealBan_PolType' in policyType and self.__realBan == True: RealBanPolTypeActions(self.__granularity, self.__name, res, da, csAPI, setup)
def run(self): """ Do actions required to notify users. Mandatory keyword arguments: - Granularity Optional keyword arguments: - SiteType - ServiceType - ResourceType """ # Initializing variables nc = NotificationClient() # raise alarms, right now makes a simple notification if 'Granularity' not in self.kw['Params'].keys(): raise ValueError, "You have to provide a argument Granularity = <desired_granularity>" if self.new_status['Action']: notif = "%s %s is perceived as" % (self.granularity, self.name) notif = notif + " %s. Reason: %s." % (self.new_status['Status'], self.new_status['Reason']) users_to_notify = self._getUsersToNotify() for notif in users_to_notify: for user in notif['Users']: if 'Web' in notif['Notifications']: gLogger.info("Sending web notification to user %s" % user) nc.addNotificationForUser(user, notif) if 'Mail' in notif['Notifications']: gLogger.info("Sending mail notification to user %s" % user) was = self.rsClient.getElementHistory( self.granularity, elementName=self.name, statusType=self.status_type, meta={ "order": "DESC", 'limit': 1, "columns": ['Status', 'Reason', 'DateEffective'] }) #[0] if not was['OK']: gLogger.error(was['Message']) continue was = was['Value'][0] mailMessage = """ ---TESTING--- -------------------------------------------------------------------------------- RSS changed the status of the following resource: Granularity:\t%s Name:\t\t%s New status:\t%s Reason:\t\t%s Was:\t\t%s (%s) since %s Setup:\t\t%s If you think RSS took the wrong decision, please set the status manually: Use: dirac-rss-set-status -g <granularity> -n <element_name> -s <desired_status> [-t status_type] (if you omit the optional last part of the command, all status types are matched.) This notification has been sent according to those parameters: %s """ % (self.granularity, self.name, self.new_status['Status'], self.new_status['Reason'], was[0], was[1], was[2], CS.getSetup(), str(users_to_notify)) # Actually send the mail! resUser = self.rmClient.getUserRegistryCache(user) if not resUser['OK']: gLogger.error(resUser['Message']) continue resUser = resUser['Value'][0][2] nc.sendMail( resUser, '[RSS][%s][%s] %s -> %s' % (self.granularity, self.name, self.new_status['Status'], was[0]), mailMessage) ################################################################################ #EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF
def run(self): """Implement real ban""" setup = CS.getSetup() if self.new_status['Action']: if self.granularity == 'Site': banList = da.getBannedSites() if not banList['OK']: print banList['Message'] return banList if self.new_status['Status'] == 'Banned': if self.name not in banList: banSite = da.banSiteFromMask(self.name, self.new_status['Reason']) if not banSite['OK']: print banSite['Message'] return banSite address = CS.getOperationMails( 'Production' ) if 'Production' in setup else '*****@*****.**' subject = '%s is banned for %s setup' % (self.name, setup) body = 'Site %s is removed from site mask for %s ' % ( self.name, setup) body += 'setup by the DIRAC RSS on %s.\n\n' % ( time.asctime()) body += 'Comment:\n%s' % self.new_status['Reason'] da.sendMail(address, subject, body) else: if self.name in banList: addSite = da.addSiteInMask(self.name, self.new_status['Reason']) if not addSite['OK']: print addSite return addSite address = CS.getOperationMails( 'Production' ) if setup == 'LHCb-Production' else '*****@*****.**' subject = '%s is added in site mask for %s setup' % ( self.name, setup) body = 'Site %s is added to the site mask for %s ' % ( self.name, setup) body += 'setup by the DIRAC RSS on %s.\n\n' % ( time.asctime()) body += 'Comment:\n%s' % self.new_status['Reason'] da.sendMail(address, subject, body) elif self.granularity == 'StorageElement': presentReadStatus = CS.getSEStatus(self.name, 'ReadAccess') if self.new_status['Status'] == 'Banned': if presentReadStatus != 'InActive': csAPI.setOption( "/Resources/StorageElements/%s/ReadAccess" % (self.name), "InActive") csAPI.setOption( "/Resources/StorageElements/%s/WriteAccess" % (self.name), "InActive") csAPI.commit() address = CS.getOperationMails( 'Production' ) if 'Production' in setup else '*****@*****.**' subject = '%s is banned for %s setup' % (self.name, setup) body = 'SE %s is removed from mask for %s ' % ( self.name, setup) body += 'setup by the DIRAC RSS on %s.\n\n' % ( time.asctime()) body += 'Comment:\n%s' % self.new_status['Reason'] da.sendMail(address, subject, body) else: if presentReadStatus == 'InActive': csAPI.setOption( "/Resources/StorageElements/%s/ReadAccess" % (self.name), "Active") csAPI.setOption( "/Resources/StorageElements/%s/WriteAccess" % (self.name), "Active") csRes = csAPI.commit() if not csRes['OK']: print csRes['Message'] return csRes address = CS.getOperationMails( 'Production' ) if setup == 'LHCb-Production' else '*****@*****.**' subject = '%s is allowed for %s setup' % (self.name, setup) body = 'SE %s is added to the mask for %s ' % ( self.name, setup) body += 'setup by the DIRAC RSS on %s.\n\n' % ( time.asctime()) body += 'Comment:\n%s' % self.new_status['Reason'] da.sendMail(address, subject, body) ################################################################################ #EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF
def run(self): """Implement real ban""" setup = CS.getSetup() if self.new_status['Action']: if self.granularity == 'Site': banList = da.getBannedSites() if not banList[ 'OK' ]: print banList[ 'Message' ] return banList if self.new_status['Status'] == 'Banned': if self.name not in banList: banSite = da.banSiteFromMask( self.name, self.new_status['Reason'] ) if not banSite[ 'OK' ]: print banSite[ 'Message' ] return banSite address = CS.getOperationMails('Production') if 'Production' in setup else '*****@*****.**' subject = '%s is banned for %s setup' %(self.name, setup) body = 'Site %s is removed from site mask for %s ' %(self.name, setup) body += 'setup by the DIRAC RSS on %s.\n\n' %(time.asctime()) body += 'Comment:\n%s' %self.new_status['Reason'] da.sendMail(address,subject,body) else: if self.name in banList: addSite = da.addSiteInMask(self.name, self.new_status['Reason']) if not addSite[ 'OK' ]: print addSite return addSite address = CS.getOperationMails('Production') if setup == 'LHCb-Production' else '*****@*****.**' subject = '%s is added in site mask for %s setup' % (self.name, setup) body = 'Site %s is added to the site mask for %s ' % (self.name, setup) body += 'setup by the DIRAC RSS on %s.\n\n' % (time.asctime()) body += 'Comment:\n%s' %self.new_status['Reason'] da.sendMail(address,subject,body) elif self.granularity == 'StorageElement': presentReadStatus = CS.getSEStatus( self.name, 'ReadAccess') if self.new_status['Status'] == 'Banned': if presentReadStatus != 'InActive': csAPI.setOption("/Resources/StorageElements/%s/ReadAccess" %(self.name), "InActive") csAPI.setOption("/Resources/StorageElements/%s/WriteAccess" %(self.name), "InActive") csAPI.commit() address = CS.getOperationMails('Production') if 'Production' in setup else '*****@*****.**' subject = '%s is banned for %s setup' %(self.name, setup) body = 'SE %s is removed from mask for %s ' %(self.name, setup) body += 'setup by the DIRAC RSS on %s.\n\n' %(time.asctime()) body += 'Comment:\n%s' %self.new_status['Reason'] da.sendMail(address,subject,body) else: if presentReadStatus == 'InActive': csAPI.setOption("/Resources/StorageElements/%s/ReadAccess" %(self.name), "Active") csAPI.setOption("/Resources/StorageElements/%s/WriteAccess" %(self.name), "Active") csRes = csAPI.commit() if not csRes[ 'OK' ]: print csRes[ 'Message' ] return csRes address = CS.getOperationMails('Production') if setup == 'LHCb-Production' else '*****@*****.**' subject = '%s is allowed for %s setup' %(self.name, setup) body = 'SE %s is added to the mask for %s ' %(self.name, setup) body += 'setup by the DIRAC RSS on %s.\n\n' %(time.asctime()) body += 'Comment:\n%s' %self.new_status['Reason'] da.sendMail(address,subject,body) ################################################################################ #EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF
def enforce(self, pdpIn=None, rsDBIn=None, rmDBIn=None, ncIn=None, setupIn=None, daIn=None, csAPIIn=None, knownInfo=None): """ enforce policies, using a PDP (Policy Decision Point), based on self.__granularity (optional) self.__name (optional) self.__status (optional) self.__formerStatus (optional) self.__reason (optional) self.__siteType (optional) self.__serviceType (optional) self.__realBan (optional) self.__user (optional) self.__futurePolicyType (optional) self.__futureGranularity (optional) :params: :attr:`pdpIn`: a custom PDP object (optional) :attr:`rsDBIn`: a custom (statuses) database object (optional) :attr:`rmDBIn`: a custom (management) database object (optional) :attr:`setupIn`: a string with the present setup (optional) :attr:`ncIn`: a custom notification client object (optional) :attr:`daIn`: a custom DiracAdmin object (optional) :attr:`csAPIIn`: a custom CSAPI object (optional) :attr:`knownInfo`: a string of known provided information (optional) """ #PDP if pdpIn is not None: pdp = pdpIn else: # Use standard DIRAC PDP from DIRAC.ResourceStatusSystem.PolicySystem.PDP import PDP pdp = PDP(self.VOExtension, granularity=self.__granularity, name=self.__name, status=self.__status, formerStatus=self.__formerStatus, reason=self.__reason, siteType=self.__siteType, serviceType=self.__serviceType, resourceType=self.__resourceType, useNewRes=self.useNewRes) #DB if rsDBIn is not None: rsDB = rsDBIn else: # Use standard DIRAC DB from DIRAC.ResourceStatusSystem.DB.ResourceStatusDB import ResourceStatusDB rsDB = ResourceStatusDB() if rmDBIn is not None: rmDB = rmDBIn else: # Use standard DIRAC DB from DIRAC.ResourceStatusSystem.DB.ResourceManagementDB import ResourceManagementDB rmDB = ResourceManagementDB() #setup if setupIn is not None: setup = setupIn else: # get present setup setup = CS.getSetup()['Value'] #notification client if ncIn is not None: nc = ncIn else: from DIRAC.FrameworkSystem.Client.NotificationClient import NotificationClient nc = NotificationClient() #DiracAdmin if daIn is not None: da = daIn else: from DIRAC.Interfaces.API.DiracAdmin import DiracAdmin da = DiracAdmin() #CSAPI if csAPIIn is not None: csAPI = csAPIIn else: from DIRAC.ConfigurationSystem.Client.CSAPI import CSAPI csAPI = CSAPI() ################### # policy decision # ################### resDecisions = pdp.takeDecision(knownInfo=knownInfo) assert (type(resDecisions) == dict and resDecisions != {}) res = resDecisions['PolicyCombinedResult'] actionBaseMod = "DIRAC.ResourceStatusSystem.PolicySystem.Actions" # Security mechanism in case there is no PolicyType returned if res == {}: EmptyPolTypeActions(self.__granularity, self.__name, resDecisions, res) else: policyType = res['PolicyType'] if 'Resource_PolType' in policyType: m = Utils.voimport(actionBaseMod + ".Resource_PolType", self.VOExtension) m.ResourcePolTypeActions(self.__granularity, self.__name, resDecisions, res, rsDB, rmDB) if 'Alarm_PolType' in policyType: m = Utils.voimport(actionBaseMod + ".Alarm_PolType", self.VOExtension) m.AlarmPolTypeActions(self.__name, res, nc, setup, rsDB, rmDB, Granularity=self.__granularity, SiteType=self.__siteType, ServiceType=self.__serviceType, ResourceType=self.__resourceType) if 'RealBan_PolType' in policyType and self.__realBan == True: m = Utils.voimport(actionBaseMod + ".RealBan_PolType", self.VOExtension) m.RealBanPolTypeActions(self.__granularity, self.__name, res, da, csAPI, setup)