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 )
Exemple #2
0
 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]
Exemple #3
0
  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
Exemple #4
0
 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]
Exemple #5
0
  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)
Exemple #6
0
    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
Exemple #7
0
    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
Exemple #8
0
  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
Exemple #9
0
    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)