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 test_getStuffToCheck(self): for g in ValidRes: res = self.rsDB.getStuffToCheck(g, CS.getTypedDictRootedAt("CheckingFreqs/SitesFreqs"), 3) self.assertEqual(res, []) res = self.rsDB.getStuffToCheck(g, CS.getTypedDictRootedAt("CheckingFreqs/SitesFreqs")) self.assertEqual(res, []) res = self.rsDB.getStuffToCheck(g, None, None, "aaa") self.assertEqual(res, [])
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 test_getStuffToCheck(self): for g in ValidRes: res = self.rsDB.getStuffToCheck( g, CS.getTypedDictRootedAt("CheckingFreqs/SitesFreqs"), 3) self.assertEqual(res, []) res = self.rsDB.getStuffToCheck( g, CS.getTypedDictRootedAt("CheckingFreqs/SitesFreqs")) self.assertEqual(res, []) res = self.rsDB.getStuffToCheck(g, None, None, 'aaa') self.assertEqual(res, [])
def initialize(self): # Attribute defined outside __init__ # pylint: disable-msg=W0201 try: self.rsClient = ResourceStatusClient() self.sitesFreqs = CS.getTypedDictRootedAtOperations( 'CheckingFreqs/SitesFreqs') self.sitesToBeChecked = Queue.Queue() self.siteNamesInCheck = [] 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') for _i in xrange(self.maxNumberOfThreads): self.threadPool.generateJobAndQueueIt(self._executeCheck, args=(None, )) return S_OK() except Exception: errorStr = "SSInspectorAgent initialization" self.log.exception(errorStr) return S_ERROR(errorStr)
def initialize( self ): # Attribute defined outside __init__ # pylint: disable-msg=W0201 try: self.rsClient = ResourceStatusClient() self.resourcesFreqs = CS.getTypedDictRootedAtOperations( 'CheckingFreqs/ResourcesFreqs' ) self.resourcesToBeChecked = Queue.Queue() self.resourceNamesInCheck = [] 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' ) for _i in xrange( self.maxNumberOfThreads ): self.threadPool.generateJobAndQueueIt( self._executeCheck, args = ( None, ) ) return S_OK() except Exception: errorStr = "RSInspectorAgent initialization" self.log.exception( errorStr ) return S_ERROR( errorStr )
def _syncStorageElements(self): # Get StorageElements from the CS and the DB CSSEs = set(CS.getSEs()) #DBSEs = set((s[0] for s in Utils.unpack(self.rsClient.getStorageElement()))) ses = self.rsClient.getStorageElement() if not ses['OK']: gLogger.error(ses['Message']) return ses DBSEs = set([se[0] for se in ses['Value']]) # Remove storageElements that are in DB but not in CS for se in DBSEs - CSSEs: #Utils.protect2(self.rsClient.removeElement, 'StorageElement', se ) res = self.rsClient.removeElement('StorageElement', se) if not res['OK']: gLogger.error(res['Message']) return res # Add new storage elements gLogger.info( "Updating %d StorageElements in DB (%d on CS vs %d on DB)" % (len(CSSEs - DBSEs), len(CSSEs), len(DBSEs))) for SE in CSSEs - DBSEs: srm = CS.getSEHost(SE) if not srm: gLogger.warn("%s has no srm URL in CS!!!" % SE) continue #siteInGOCDB = Utils.unpack(self.GOCDBClient.getServiceEndpointInfo( 'hostname', srm )) siteInGOCDB = self.GOCDBClient.getServiceEndpointInfo( 'hostname', srm) if siteInGOCDB['OK']: siteInGOCDB = siteInGOCDB['Value'] else: gLogger.error("Error getting hostname for %s from GOCDB!!!" % srm) continue if siteInGOCDB == []: gLogger.warn("%s is not in GOCDB!!!" % srm) continue siteInGOCDB = siteInGOCDB[0]['SITENAME'] #Utils.protect2(self.rsClient.addOrModifyStorageElement, SE, srm, siteInGOCDB ) res = self.rsClient.addOrModifyStorageElement(SE, srm, siteInGOCDB) if not res['OK']: gLogger.error(res['Message']) return res
def _syncStorageElements( self ): # Get StorageElements from the CS and the DB CSSEs = set(CS.getSEs()) #DBSEs = set((s[0] for s in Utils.unpack(self.rsClient.getStorageElement()))) ses = self.rsClient.getStorageElement() if not ses[ 'OK' ]: gLogger.error( ses[ 'Message' ] ) return ses DBSEs = set( [ se[0] for se in ses[ 'Value' ] ] ) # Remove storageElements that are in DB but not in CS for se in DBSEs - CSSEs: #Utils.protect2(self.rsClient.removeElement, 'StorageElement', se ) res = self.rsClient.removeElement( 'StorageElement', se ) if not res[ 'OK' ]: gLogger.error( res[ 'Message' ] ) return res # Add new storage elements gLogger.info("Updating %d StorageElements in DB (%d on CS vs %d on DB)" % (len(CSSEs - DBSEs), len(CSSEs), len(DBSEs))) for SE in CSSEs - DBSEs: srm = CS.getSEHost( SE ) if not srm: gLogger.warn("%s has no srm URL in CS!!!" % SE) continue #siteInGOCDB = Utils.unpack(self.GOCDBClient.getServiceEndpointInfo( 'hostname', srm )) siteInGOCDB = self.GOCDBClient.getServiceEndpointInfo( 'hostname', srm ) if siteInGOCDB[ 'OK' ]: siteInGOCDB = siteInGOCDB[ 'Value' ] else: gLogger.error("Error getting hostname for %s from GOCDB!!!" % srm) continue if siteInGOCDB == []: gLogger.warn("%s is not in GOCDB!!!" % srm) continue siteInGOCDB = siteInGOCDB[ 0 ][ 'SITENAME' ] #Utils.protect2(self.rsClient.addOrModifyStorageElement, SE, srm, siteInGOCDB ) res = self.rsClient.addOrModifyStorageElement( SE, srm, siteInGOCDB ) if not res[ 'OK' ]: gLogger.error( res[ 'Message' ] ) return res
def _syncRegistryUsers(self): from DIRAC.ResourceStatusSystem.Utilities import CS users = CS.getTypedDictRootedAt("Users", root= "/Registry") for u in users: if type(users[u]['DN']) == list: users[u]['DN'] = users[u]['DN'][0] if type(users[u]['Email']) == list: users[u]['Email'] = users[u]['Email'][0] users[u]['DN'] = users[u]['DN'].split('=')[-1] self.rmDB.registryAddUser(u, users[u]['DN'].lower(), users[u]['Email'].lower())
def __getSpaceTokenOccupancyCandidates( self ): ''' Gets the candidates to execute the command ''' elementsToCheck = [] spaceEndpoints = CS.getSpaceTokenEndpoints() spaceTokens = CS.getSpaceTokens() for site,siteDict in spaceEndpoints.items(): if not isinstance( siteDict, dict ): continue if not siteDict.has_key( 'Endpoint' ): continue for spaceToken in spaceTokens: elementsToCheck.append( ( siteDict[ 'Endpoint' ], spaceToken, ) ) return elementsToCheck
def _syncRegistryUsers(self): from DIRAC.ResourceStatusSystem.Utilities import CS users = CS.getTypedDictRootedAt("Users", root="/Registry") for u in users: if type(users[u]['DN']) == list: users[u]['DN'] = users[u]['DN'][0] if type(users[u]['Email']) == list: users[u]['Email'] = users[u]['Email'][0] users[u]['DN'] = users[u]['DN'].split('=')[-1] self.rmDB.registryAddUser(u, users[u]['DN'].lower(), users[u]['Email'].lower())
def __syncNode(self, NodeInCS, resourcesInDB, resourceType, serviceType, site="NULL"): nodesToUpdate = NodeInCS - resourcesInDB if len(nodesToUpdate) > 0: gLogger.debug(str(NodeInCS)) gLogger.debug(str(nodesToUpdate)) # Update Service table siteInGOCDB = [ self.__getServiceEndpointInfo(node) for node in nodesToUpdate ] siteInGOCDB = Utils.list_sanitize(siteInGOCDB) #sites = [Utils.unpack(getDIRACSiteName(s[0]['SITENAME'])) for s in siteInGOCDB] sites = [] for sInGOCDB in siteInGOCDB: siteName = getDIRACSiteName(sInGOCDB[0]['SITENAME']) if not siteName['OK']: gLogger.error(siteName['Message']) return siteName sites.append(siteName['Value']) sites = Utils.list_sanitize(Utils.list_flatten(sites)) _ = [self.__updateService(s, serviceType) for s in sites] # Update Resource table for node in NodeInCS: if serviceType == "Computing": resourceType = CS.getCEType(site, node) if node not in resourcesInDB and node is not None: try: siteInGOCDB = self.__getServiceEndpointInfo( node)[0]['SITENAME'] except IndexError: # No INFO in GOCDB: Node does not exist gLogger.warn( "Node %s is not in GOCDB!! Considering that it does not exists!" % node) continue assert (type(siteInGOCDB) == str) #Utils.protect2(self.rsClient.addOrModifyResource, node, resourceType, serviceType, site, siteInGOCDB ) res = self.rsClient.addOrModifyResource( node, resourceType, serviceType, site, siteInGOCDB) if not res['OK']: gLogger.error(res['Message']) return res resourcesInDB.add(node)
def __getSpaceTokenOccupancyCandidates(self): ''' Gets the candidates to execute the command ''' elementsToCheck = [] spaceEndpoints = CS.getSpaceTokenEndpoints() spaceTokens = CS.getSpaceTokens() for site, siteDict in spaceEndpoints.items(): if not isinstance(siteDict, dict): continue if not siteDict.has_key('Endpoint'): continue for spaceToken in spaceTokens: elementsToCheck.append(( siteDict['Endpoint'], spaceToken, )) return elementsToCheck
def _syncRegistryUsers(self): users = CS.getTypedDictRootedAt("Users", root="/Registry") usersInCS = set(users.keys()) #usersInDB = set((u[0] for u in Utils.unpack(self.rmClient.getUserRegistryCache()))) usersInCache = self.rmClient.getUserRegistryCache() if not usersInCache['OK']: gLogger.error(usersInCache['Message']) return usersInCache usersInDB = set( [userInCache[0] for userInCache in usersInCache['Value']]) usersToAdd = usersInCS - usersInDB usersToDel = usersInDB - usersInCS gLogger.info("Updating Registry Users: + %d, - %d" % (len(usersToAdd), len(usersToDel))) if len(usersToAdd) > 0: gLogger.debug(str(usersToAdd)) if len(usersToDel) > 0: gLogger.debug(str(usersToDel)) for u in usersToAdd: if type(users[u]['DN']) == list: users[u]['DN'] = users[u]['DN'][0] if type(users[u]['Email']) == list: users[u]['Email'] = users[u]['Email'][0] users[u]['DN'] = users[u]['DN'].split('=')[-1] #Utils.unpack(self.rmClient.addOrModifyUserRegistryCache( u, users[u]['DN'], users[u]['Email'].lower())) res = self.rmClient.addOrModifyUserRegistryCache( u, users[u]['DN'], users[u]['Email'].lower()) if not res['OK']: gLogger.error(res['Message']) return res for u in usersToDel: #Utils.protect2(self.rmClient.deleteUserRegistryCache, u) res = self.rmClient.deleteUserRegistryCache(u) if not res['OK']: gLogger.error(res['Message']) return res ################################################################################ #EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF
def _syncRegistryUsers(self): users = CS.getTypedDictRootedAt("Users", root= "/Registry") usersInCS = set(users.keys()) #usersInDB = set((u[0] for u in Utils.unpack(self.rmClient.getUserRegistryCache()))) usersInCache = self.rmClient.getUserRegistryCache() if not usersInCache[ 'OK' ]: gLogger.error( usersInCache[ 'Message' ] ) return usersInCache usersInDB = set( [ userInCache[ 0 ] for userInCache in usersInCache[ 'Value' ] ] ) usersToAdd = usersInCS - usersInDB usersToDel = usersInDB - usersInCS gLogger.info("Updating Registry Users: + %d, - %d" % (len(usersToAdd), len(usersToDel))) if len(usersToAdd) > 0: gLogger.debug(str(usersToAdd)) if len(usersToDel) > 0: gLogger.debug(str(usersToDel)) for u in usersToAdd: if type(users[u]['DN']) == list: users[u]['DN'] = users[u]['DN'][0] if type(users[u]['Email']) == list: users[u]['Email'] = users[u]['Email'][0] users[u]['DN'] = users[u]['DN'].split('=')[-1] #Utils.unpack(self.rmClient.addOrModifyUserRegistryCache( u, users[u]['DN'], users[u]['Email'].lower())) res = self.rmClient.addOrModifyUserRegistryCache( u, users[u]['DN'], users[u]['Email'].lower() ) if not res[ 'OK' ]: gLogger.error( res[ 'Message' ] ) return res for u in usersToDel: #Utils.protect2(self.rmClient.deleteUserRegistryCache, u) res = self.rmClient.deleteUserRegistryCache( u ) if not res[ 'OK' ]: gLogger.error( res[ 'Message' ] ) return res ################################################################################ #EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF
def getUsersToNotify(setup, kwargs): """Get a list of users to notify (helper function for AlarmPolTypeActions) Optional keyword arguments: - Granularity - SiteType - ServiceType - ResourceType """ notifications = [] groups = CS.getTypedDictRootedAt("AssigneeGroups/" + setup) for k in groups: if Utils.dictMatch(kwargs, groups[k]): notifications.append({ 'Users': groups[k]['Users'], 'Notifications': groups[k]['Notifications'] }) return notifications
def __syncNode(self, NodeInCS, resourcesInDB, resourceType, serviceType, site = "NULL"): nodesToUpdate = NodeInCS - resourcesInDB if len(nodesToUpdate) > 0: gLogger.debug(str(NodeInCS)) gLogger.debug(str(nodesToUpdate)) # Update Service table siteInGOCDB = [self.__getServiceEndpointInfo(node) for node in nodesToUpdate] siteInGOCDB = Utils.list_sanitize(siteInGOCDB) #sites = [Utils.unpack(getDIRACSiteName(s[0]['SITENAME'])) for s in siteInGOCDB] sites = [] for sInGOCDB in siteInGOCDB: siteName = getDIRACSiteName( sInGOCDB[ 0 ][ 'SITENAME' ] ) if not siteName[ 'OK' ]: gLogger.error( siteName[ 'Message' ] ) return siteName sites.append( siteName[ 'Value' ] ) sites = Utils.list_sanitize( Utils.list_flatten( sites ) ) _ = [ self.__updateService(s, serviceType) for s in sites ] # Update Resource table for node in NodeInCS: if serviceType == "Computing": resourceType = CS.getCEType(site, node) if node not in resourcesInDB and node is not None: try: siteInGOCDB = self.__getServiceEndpointInfo(node)[0]['SITENAME'] except IndexError: # No INFO in GOCDB: Node does not exist gLogger.warn("Node %s is not in GOCDB!! Considering that it does not exists!" % node) continue assert(type(siteInGOCDB) == str) #Utils.protect2(self.rsClient.addOrModifyResource, node, resourceType, serviceType, site, siteInGOCDB ) res = self.rsClient.addOrModifyResource( node, resourceType, serviceType, site, siteInGOCDB ) if not res[ 'OK' ]: gLogger.error( res[ 'Message' ] ) return res resourcesInDB.add( node )
def test_DBFail(self): self.mock_DB._query.return_value = {"OK": False, "Message": "boh"} self.mock_DB._update.return_value = {"OK": False, "Message": "boh"} from DIRAC.ResourceStatusSystem.DB.ResourceStatusDB import RSSDBException self.assertRaises( RSSDBException, self.rsDB.addOrModifySite, "CNAF", "T1", "INFN-FERRARA", "Banned", "test reason", datetime.datetime.utcnow(), "testOP", datetime.datetime.utcnow() + datetime.timedelta(minutes=10), ) self.assertRaises(RSSDBException, self.rsDB.setSiteStatus, "CNAF", "Active", "reasons", "Federico") self.assertRaises( RSSDBException, self.rsDB._addSiteRow, "Ferrara", "T2", "INFN-FERRARA", "Active", "reasons", datetime.datetime.utcnow(), datetime.datetime.utcnow(), datetime.datetime.utcnow() + datetime.timedelta(minutes=10), "Federico", ) self.assertRaises( RSSDBException, self.rsDB._addSiteHistoryRow, "Ferrara", "Active", "reasons", datetime.datetime.utcnow(), datetime.datetime.utcnow(), datetime.datetime.utcnow() + datetime.timedelta(minutes=10), "Federico", ) self.assertRaises( RSSDBException, self.rsDB.addOrModifyService, "Computing@CERN", "Computing", "CERN", "Banned", "test reason", datetime.datetime.utcnow(), "testOP", datetime.datetime.utcnow() + datetime.timedelta(minutes=10), ) self.assertRaises(RSSDBException, self.rsDB.setServiceStatus, "Computing@CERN", "Active", "reasons", "Federico") self.assertRaises( RSSDBException, self.rsDB._addServiceRow, "Computing@CERN", "Computing", "Ferrara", "Active", "reasons", datetime.datetime.utcnow(), datetime.datetime.utcnow(), datetime.datetime.utcnow() + datetime.timedelta(minutes=10), "Federico", ) self.assertRaises( RSSDBException, self.rsDB._addServiceHistoryRow, "Computing@CERN", "Active", "reasons", datetime.datetime.utcnow(), datetime.datetime.utcnow(), datetime.datetime.utcnow() + datetime.timedelta(minutes=10), "Federico", ) self.assertRaises( RSSDBException, self.rsDB.addOrModifyResource, "CE01", "T1", "Computing", "CNAF", "INFN-T1", "Banned", "test reason", datetime.datetime.utcnow(), "testOP", datetime.datetime.utcnow() + datetime.timedelta(minutes=10), ) self.assertRaises(RSSDBException, self.rsDB.setResourceStatus, "CE01", "Active", "reasons", "Federico") self.assertRaises( RSSDBException, self.rsDB._addResourcesRow, "CE01", "CE", "Computing", "Ferrara", "INFN-FE", "Active", "reasons", datetime.datetime.utcnow(), datetime.datetime.utcnow(), datetime.datetime.utcnow() + datetime.timedelta(minutes=10), "Federico", ) self.assertRaises( RSSDBException, self.rsDB._addResourcesHistoryRow, "CE01", "Active", "reasons", datetime.datetime.utcnow(), datetime.datetime.utcnow(), datetime.datetime.utcnow() + datetime.timedelta(minutes=10), "Federico", ) self.assertRaises(RSSDBException, self.rsDB.getStatusList) self.assertRaises(RSSDBException, self.rsDB.getEndings, "Resources") self.assertRaises(RSSDBException, self.rsDB.getTablesWithHistory) self.assertRaises(RSSDBException, self.rsDB.addStatus, "") self.assertRaises(RSSDBException, self.rsDB.removeStatus, "") self.assertRaises(RSSDBException, self.rsDB.setDateEnd, "Site", "CNAF", datetime.datetime.utcnow()) self.assertRaises(RSSDBException, self.rsDB.setMonitoredToBeChecked, "Service", "Site", "CNAF") self.assertRaises(RSSDBException, self.rsDB.rankRes, "Site", 30) self.assertRaises(RSSDBException, self.rsDB.getServiceStats, "xxx") self.assertRaises(RSSDBException, self.rsDB.getResourceStats, "Site", "xxx") self.assertRaises(RSSDBException, self.rsDB.getStorageElementsStats, "Site", "xxx", "Read") self.assertRaises(RSSDBException, self.rsDB.getCountries, "Site") # print self.defaultTestResult() for g in ["Site", "Service", "Resource"]: self.assertRaises(RSSDBException, self.rsDB.getTypesList, g) self.assertRaises(RSSDBException, self.rsDB.removeType, g, "xx") for g in ValidRes: self.assertRaises(RSSDBException, self.rsDB.getMonitoredsList, g) self.assertRaises( RSSDBException, self.rsDB.getStuffToCheck, g, CS.getTypedDictRootedAt("CheckingFreqs/SitesFreqs"), 3 ) self.assertRaises(RSSDBException, self.rsDB.removeRow, g, "xx", datetime.datetime.utcnow()) self.assertRaises(RSSDBException, self.rsDB.setLastMonitoredCheckTime, g, "xxx") self.assertRaises(RSSDBException, self.rsDB.setMonitoredReason, g, "xxx", "x", "x")
""" DIRAC.ResourceStatusSystem package """ from DIRAC.ResourceStatusSystem.Utilities import CS __gencfg = CS.getTypedDictRootedAt( "GeneralConfig" ) ValidRes = __gencfg[ 'Resource' ] ValidStatus = __gencfg[ 'Status' ] ValidPolicyResult = __gencfg[ 'PolicyResult' ] + __gencfg[ 'Status' ] ValidSiteType = __gencfg[ 'SiteType' ] ValidServiceType = __gencfg[ 'ServiceType' ] ValidResourceType = __gencfg[ 'ResourceType' ] ValidService = ValidServiceType PolicyTypes = __gencfg[ 'PolicyTypes' ] CheckingFreqs = CS.getTypedDictRootedAt("CheckingFreqs") ############################################################################# # Web views ############################################################################# views_panels = { 'Site' : ['Site_Panel', 'Service_Computing_Panel', 'Service_Storage_Panel', 'Service_VOMS_Panel', 'Service_VO-BOX_Panel'], 'Resource' : ['Resource_Panel'], 'StorageElement' : ['SE_Panel'] }
""" Backward compatibility. This module will probably will be removed in the future. """ from DIRAC.ResourceStatusSystem.Utilities import CS gencfg = CS.getTypedDict("GeneralConfig") ValidRes = gencfg['Resource'] ValidStatus = gencfg['Status'] ValidPolicyResult = gencfg['PolicyResult'] + gencfg['Status'] ValidSiteType = gencfg['SiteType'] ValidServiceType = gencfg['ServiceType'] ValidResourceType = gencfg['ResourceType'] ValidService = ValidServiceType PolicyTypes = gencfg['PolicyTypes']
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)
def getPolicyParameters(): return CS.getTypedDictRootedAtOperations( 'PolicyParameters' )
def _syncSites(self): """ Sync DB content with sites that are in the CS """ def getGOCTier(sitesList): return "T" + str(min([int(v) for v in CS.getSiteTiers(sitesList)])) # sites in the DB now #sitesDB = set((s[0] for s in Utils.unpack(self.rsClient.getSite()))) sites = self.rsClient.getSite() if not sites['OK']: gLogger.error(sites['Message']) return sites sitesDB = set([site[0] for site in sites['Value']]) # sites in CS now sitesCS = set(CS.getSites()) gLogger.info("Syncing Sites from CS: %d sites in CS, %d sites in DB" % (len(sitesCS), len(sitesDB))) # remove sites and associated resources, services, and storage # elements from the DB that are not in the CS: for s in sitesDB - sitesCS: gLogger.info("Purging Site %s (not in CS anymore)" % s) self.__purge_site(s) # add to DB what is missing gLogger.info("Updating %d Sites in DB" % len(sitesCS - sitesDB)) for site in sitesCS - sitesDB: siteType = site.split(".")[0] # DIRAC Tier tier = "T" + str(CS.getSiteTier(site)) if siteType == "LCG": # Grid Name of the site #gridSiteName = Utils.unpack(getGOCSiteName(site)) gridSiteName = getGOCSiteName(site) if not gridSiteName['OK']: gLogger.error(gridSiteName['Message']) return gridSiteName gridSiteName = gridSiteName['Value'] # Grid Tier (with a workaround!) #DIRACSitesOfGridSites = Utils.unpack(getDIRACSiteName(gridSiteName)) DIRACSitesOfGridSites = getDIRACSiteName(gridSiteName) if not DIRACSitesOfGridSites['OK']: gLogger.error(DIRACSitesOfGridSites['Message']) return DIRACSitesOfGridSites DIRACSitesOfGridSites = DIRACSitesOfGridSites['Value'] if len(DIRACSitesOfGridSites) == 1: gt = tier else: gt = getGOCTier(DIRACSitesOfGridSites) #Utils.protect2(self.rsClient.addOrModifyGridSite, gridSiteName, gt) res = self.rsClient.addOrModifyGridSite(gridSiteName, gt) if not res['OK']: gLogger.error(res['Message']) return res #Utils.protect2(self.rsClient.addOrModifySite, site, tier, gridSiteName ) res = self.rsClient.addOrModifySite(site, tier, gridSiteName) if not res['OK']: gLogger.error(res['Message']) return res elif siteType == "DIRAC": #Utils.protect2(self.rsClient.addOrModifySite, site, tier, "NULL" ) res = self.rsClient.addOrModifySite(site, tier, "NULL") if not res['OK']: gLogger.error(res['Message']) return res
def _syncSites( self ): """ Sync DB content with sites that are in the CS """ def getGOCTier(sitesList): return "T" + str(min([int(v) for v in CS.getSiteTiers(sitesList)])) # sites in the DB now #sitesDB = set((s[0] for s in Utils.unpack(self.rsClient.getSite()))) sites = self.rsClient.getSite() if not sites[ 'OK' ]: gLogger.error( sites[ 'Message' ] ) return sites sitesDB = set( [ site[0] for site in sites[ 'Value' ] ] ) # sites in CS now sitesCS = set( CS.getSites() ) gLogger.info("Syncing Sites from CS: %d sites in CS, %d sites in DB" % (len(sitesCS), len(sitesDB))) # remove sites and associated resources, services, and storage # elements from the DB that are not in the CS: for s in sitesDB - sitesCS: gLogger.info("Purging Site %s (not in CS anymore)" % s) self.__purge_site(s) # add to DB what is missing gLogger.info("Updating %d Sites in DB" % len(sitesCS - sitesDB)) for site in sitesCS - sitesDB: siteType = site.split(".")[0] # DIRAC Tier tier = "T" + str(CS.getSiteTier( site )) if siteType == "LCG": # Grid Name of the site #gridSiteName = Utils.unpack(getGOCSiteName(site)) gridSiteName = getGOCSiteName( site ) if not gridSiteName[ 'OK' ]: gLogger.error( gridSiteName[ 'Message' ] ) return gridSiteName gridSiteName = gridSiteName[ 'Value' ] # Grid Tier (with a workaround!) #DIRACSitesOfGridSites = Utils.unpack(getDIRACSiteName(gridSiteName)) DIRACSitesOfGridSites = getDIRACSiteName( gridSiteName ) if not DIRACSitesOfGridSites[ 'OK' ]: gLogger.error( DIRACSitesOfGridSites[ 'Message' ] ) return DIRACSitesOfGridSites DIRACSitesOfGridSites = DIRACSitesOfGridSites[ 'Value' ] if len( DIRACSitesOfGridSites ) == 1: gt = tier else: gt = getGOCTier( DIRACSitesOfGridSites ) #Utils.protect2(self.rsClient.addOrModifyGridSite, gridSiteName, gt) res = self.rsClient.addOrModifyGridSite( gridSiteName, gt ) if not res[ 'OK' ]: gLogger.error( res[ 'Message' ] ) return res #Utils.protect2(self.rsClient.addOrModifySite, site, tier, gridSiteName ) res = self.rsClient.addOrModifySite( site, tier, gridSiteName ) if not res[ 'OK' ]: gLogger.error( res[ 'Message' ] ) return res elif siteType == "DIRAC": #Utils.protect2(self.rsClient.addOrModifySite, site, tier, "NULL" ) res = self.rsClient.addOrModifySite( site, tier, "NULL" ) if not res[ 'OK' ]: gLogger.error( res[ 'Message' ] ) return res
import unittest from DIRAC.Core.Base import Script Script.parseCommandLine() from DIRAC.ResourceStatusSystem.Utilities.mock import Mock from DIRAC.ResourceStatusSystem.Client.JobsClient import JobsClient from DIRAC.ResourceStatusSystem.Client.PilotsClient import PilotsClient from DIRAC.ResourceStatusSystem.Client.ResourceStatusClient import ResourceStatusClient from DIRAC.ResourceStatusSystem.Client.ResourceManagementClient import ResourceManagementClient from DIRAC.ResourceStatusSystem.Utilities import CS ValidRes = CS.getTypedDictRootedAt("GeneralConfig")['Resource'] ValidStatus = CS.getTypedDictRootedAt("GeneralConfig")['Status'] ############################################################################# class ClientsTestCase( unittest.TestCase ): """ Base class for the clients test cases """ def setUp( self ): self.mockRSS = Mock() self.RSCli = ResourceStatusClient( serviceIn = self.mockRSS ) self.RMCli = ResourceManagementClient( serviceIn = self.mockRSS ) self.PilotsCli = PilotsClient() self.JobsCli = JobsClient() #############################################################################
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 test_DBFail(self): self.mock_DB._query.return_value = {'OK': False, 'Message': 'boh'} self.mock_DB._update.return_value = {'OK': False, 'Message': 'boh'} from DIRAC.ResourceStatusSystem.DB.ResourceStatusDB import RSSDBException self.assertRaises( RSSDBException, self.rsDB.addOrModifySite, 'CNAF', 'T1', 'INFN-FERRARA', 'Banned', 'test reason', datetime.datetime.utcnow(), 'testOP', datetime.datetime.utcnow() + datetime.timedelta(minutes=10)) self.assertRaises(RSSDBException, self.rsDB.setSiteStatus, 'CNAF', 'Active', 'reasons', 'Federico') self.assertRaises( RSSDBException, self.rsDB._addSiteRow, 'Ferrara', 'T2', 'INFN-FERRARA', 'Active', 'reasons', datetime.datetime.utcnow(), datetime.datetime.utcnow(), datetime.datetime.utcnow() + datetime.timedelta(minutes=10), 'Federico') self.assertRaises( RSSDBException, self.rsDB._addSiteHistoryRow, 'Ferrara', 'Active', 'reasons', datetime.datetime.utcnow(), datetime.datetime.utcnow(), datetime.datetime.utcnow() + datetime.timedelta(minutes=10), 'Federico') self.assertRaises( RSSDBException, self.rsDB.addOrModifyService, 'Computing@CERN', 'Computing', 'CERN', 'Banned', 'test reason', datetime.datetime.utcnow(), 'testOP', datetime.datetime.utcnow() + datetime.timedelta(minutes=10)) self.assertRaises(RSSDBException, self.rsDB.setServiceStatus, 'Computing@CERN', 'Active', 'reasons', 'Federico') self.assertRaises( RSSDBException, self.rsDB._addServiceRow, 'Computing@CERN', 'Computing', 'Ferrara', 'Active', 'reasons', datetime.datetime.utcnow(), datetime.datetime.utcnow(), datetime.datetime.utcnow() + datetime.timedelta(minutes=10), 'Federico') self.assertRaises( RSSDBException, self.rsDB._addServiceHistoryRow, 'Computing@CERN', 'Active', 'reasons', datetime.datetime.utcnow(), datetime.datetime.utcnow(), datetime.datetime.utcnow() + datetime.timedelta(minutes=10), 'Federico') self.assertRaises( RSSDBException, self.rsDB.addOrModifyResource, 'CE01', 'T1', 'Computing', 'CNAF', 'INFN-T1', 'Banned', 'test reason', datetime.datetime.utcnow(), 'testOP', datetime.datetime.utcnow() + datetime.timedelta(minutes=10)) self.assertRaises(RSSDBException, self.rsDB.setResourceStatus, 'CE01', 'Active', 'reasons', 'Federico') self.assertRaises( RSSDBException, self.rsDB._addResourcesRow, 'CE01', 'CE', 'Computing', 'Ferrara', 'INFN-FE', 'Active', 'reasons', datetime.datetime.utcnow(), datetime.datetime.utcnow(), datetime.datetime.utcnow() + datetime.timedelta(minutes=10), 'Federico') self.assertRaises( RSSDBException, self.rsDB._addResourcesHistoryRow, 'CE01', 'Active', 'reasons', datetime.datetime.utcnow(), datetime.datetime.utcnow(), datetime.datetime.utcnow() + datetime.timedelta(minutes=10), 'Federico') self.assertRaises(RSSDBException, self.rsDB.getStatusList) self.assertRaises(RSSDBException, self.rsDB.getEndings, 'Resources') self.assertRaises(RSSDBException, self.rsDB.getTablesWithHistory) self.assertRaises(RSSDBException, self.rsDB.addStatus, '') self.assertRaises(RSSDBException, self.rsDB.removeStatus, '') self.assertRaises(RSSDBException, self.rsDB.setDateEnd, 'Site', 'CNAF', datetime.datetime.utcnow()) self.assertRaises(RSSDBException, self.rsDB.setMonitoredToBeChecked, 'Service', 'Site', 'CNAF') self.assertRaises(RSSDBException, self.rsDB.rankRes, 'Site', 30) self.assertRaises(RSSDBException, self.rsDB.getServiceStats, 'xxx') self.assertRaises(RSSDBException, self.rsDB.getResourceStats, 'Site', 'xxx') self.assertRaises(RSSDBException, self.rsDB.getStorageElementsStats, 'Site', 'xxx', "Read") self.assertRaises(RSSDBException, self.rsDB.getCountries, 'Site') #print self.defaultTestResult() for g in ['Site', 'Service', 'Resource']: self.assertRaises(RSSDBException, self.rsDB.getTypesList, g) self.assertRaises(RSSDBException, self.rsDB.removeType, g, 'xx') for g in ValidRes: self.assertRaises(RSSDBException, self.rsDB.getMonitoredsList, g) self.assertRaises( RSSDBException, self.rsDB.getStuffToCheck, g, CS.getTypedDictRootedAt("CheckingFreqs/SitesFreqs"), 3) self.assertRaises(RSSDBException, self.rsDB.removeRow, g, 'xx', datetime.datetime.utcnow()) self.assertRaises(RSSDBException, self.rsDB.setLastMonitoredCheckTime, g, 'xxx') self.assertRaises(RSSDBException, self.rsDB.setMonitoredReason, g, 'xxx', 'x', 'x')
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)
""" DIRAC.ResourceStatusSystem.Policy.Configurations Module collects everything needed to configure policies """ __RCSID__ = "$Id: " from DIRAC.ResourceStatusSystem.Utilities import CS pp = CS.getTypedDictRootedAt("PolicyParameters") Policies = { 'DT_OnGoing_Only' : { 'Description' : "Ongoing down-times", 'module' : 'DT_Policy', 'commandIn' : ( 'GOCDBStatus_Command', 'GOCDBStatus_Command' ), 'args' : None }, 'DT_Scheduled' : { 'Description' : "Ongoing and scheduled down-times", 'module' : 'DT_Policy', 'commandInNewRes' : ( 'GOCDBStatus_Command', 'GOCDBStatus_Command' ), 'commandIn' : ( 'GOCDBStatus_Command', 'DTCached_Command' ), 'args' : ( pp["DTinHours"], ), 'Site_Panel' : [ {'WebLink': {'CommandIn': ( 'GOCDBStatus_Command', 'DTInfo_Cached_Command' ), 'args': None}},], 'Resource_Panel' : [ {'WebLink': {'CommandIn': ( 'GOCDBStatus_Command', 'DTInfo_Cached_Command' ), 'args': None}}]
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 getGOCTier(sitesList): return "T" + str(min([int(v) for v in CS.getSiteTiers(sitesList)]))
def _syncResources( self ): gLogger.info("Starting sync of Resources") # resources in the DB now #resourcesInDB = set((r[0] for r in Utils.unpack(self.rsClient.getResource()))) resources = self.rsClient.getResource() if not resources[ 'OK' ]: gLogger.error( resources[ 'Message' ] ) return resources resourcesInDB = set( [ resource[ 0 ] for resource in resources[ 'Value' ] ] ) # Site-CE / Site-SE mapping in CS now #CEinCS = Utils.unpack(getSiteCEMapping( 'LCG' )) CEinCS = getSiteCEMapping( 'LCG' ) if not CEinCS[ 'OK' ]: gLogger.error( CEinCS[ 'Message' ] ) return CEinCS CEinCS = CEinCS[ 'Value' ] # All CEs in CS now CEInCS = Utils.set_sanitize([CE for celist in CEinCS.values() for CE in celist]) # All SE Nodes in CS now SENodeInCS = set(CS.getSENodes()) # LFC Nodes in CS now LFCNodeInCS_L = set(CS.getLFCNode(readable = "ReadOnly")) LFCNodeInCS_C = set(CS.getLFCNode(readable = "ReadWrite")) # FTS Nodes in CS now FTSNodeInCS = set([v.split("/")[2][0:-5] for v in CS.getTypedDictRootedAt(root="/Resources/FTSEndpoints").values()]) # VOMS Nodes in CS now VOMSNodeInCS = set(CS.getVOMSEndpoints()) # complete list of resources in CS now resourcesInCS = CEInCS | SENodeInCS | LFCNodeInCS_L | LFCNodeInCS_C | FTSNodeInCS | VOMSNodeInCS gLogger.info(" %d resources in CS, %s resources in DB, updating %d resources" % (len(resourcesInCS), len(resourcesInDB), len(resourcesInCS)-len(resourcesInDB))) # Remove resources that are not in the CS anymore for res in resourcesInDB - resourcesInCS: gLogger.info("Purging resource %s. Reason: not in CS anywore." % res) self.__purge_resource(res) # Add to DB what is in CS now and wasn't before # CEs for site in CEinCS: self.__syncNode(set(CEinCS[site]), resourcesInDB, "", "Computing", site) # SRMs self.__syncNode(SENodeInCS, resourcesInDB, "SE", "Storage") # LFC_C self.__syncNode(LFCNodeInCS_C, resourcesInDB, "LFC_C", "Storage") # LFC_L self.__syncNode(LFCNodeInCS_L, resourcesInDB, "LFC_L", "Storage") # FTSs self.__syncNode(FTSNodeInCS, resourcesInDB, "FTS", "Storage") # VOMSs self.__syncNode(VOMSNodeInCS, resourcesInDB, "VOMS", "VOMS")
def _syncResources(self): gLogger.info("Starting sync of Resources") # resources in the DB now #resourcesInDB = set((r[0] for r in Utils.unpack(self.rsClient.getResource()))) resources = self.rsClient.getResource() if not resources['OK']: gLogger.error(resources['Message']) return resources resourcesInDB = set([resource[0] for resource in resources['Value']]) # Site-CE / Site-SE mapping in CS now #CEinCS = Utils.unpack(getSiteCEMapping( 'LCG' )) CEinCS = getSiteCEMapping('LCG') if not CEinCS['OK']: gLogger.error(CEinCS['Message']) return CEinCS CEinCS = CEinCS['Value'] # All CEs in CS now CEInCS = Utils.set_sanitize( [CE for celist in CEinCS.values() for CE in celist]) # All SE Nodes in CS now SENodeInCS = set(CS.getSENodes()) # LFC Nodes in CS now LFCNodeInCS_L = set(CS.getLFCNode(readable="ReadOnly")) LFCNodeInCS_C = set(CS.getLFCNode(readable="ReadWrite")) # FTS Nodes in CS now FTSNodeInCS = set([ v.split("/")[2][0:-5] for v in CS.getTypedDictRootedAt( root="/Resources/FTSEndpoints").values() ]) # VOMS Nodes in CS now VOMSNodeInCS = set(CS.getVOMSEndpoints()) # complete list of resources in CS now resourcesInCS = CEInCS | SENodeInCS | LFCNodeInCS_L | LFCNodeInCS_C | FTSNodeInCS | VOMSNodeInCS gLogger.info( " %d resources in CS, %s resources in DB, updating %d resources" % (len(resourcesInCS), len(resourcesInDB), len(resourcesInCS) - len(resourcesInDB))) # Remove resources that are not in the CS anymore for res in resourcesInDB - resourcesInCS: gLogger.info("Purging resource %s. Reason: not in CS anywore." % res) self.__purge_resource(res) # Add to DB what is in CS now and wasn't before # CEs for site in CEinCS: self.__syncNode(set(CEinCS[site]), resourcesInDB, "", "Computing", site) # SRMs self.__syncNode(SENodeInCS, resourcesInDB, "SE", "Storage") # LFC_C self.__syncNode(LFCNodeInCS_C, resourcesInDB, "LFC_C", "Storage") # LFC_L self.__syncNode(LFCNodeInCS_L, resourcesInDB, "LFC_L", "Storage") # FTSs self.__syncNode(FTSNodeInCS, resourcesInDB, "FTS", "Storage") # VOMSs self.__syncNode(VOMSNodeInCS, resourcesInDB, "VOMS", "VOMS")
""" DIRAC.ResourceStatusSystem package """ from DIRAC.ResourceStatusSystem.Utilities import CS __gencfg = CS.getTypedDictRootedAt("GeneralConfig") ValidRes = __gencfg['Resource'] ValidStatus = __gencfg['Status'] ValidPolicyResult = __gencfg['PolicyResult'] + __gencfg['Status'] ValidSiteType = __gencfg['SiteType'] ValidServiceType = __gencfg['ServiceType'] ValidResourceType = __gencfg['ResourceType'] ValidService = ValidServiceType PolicyTypes = __gencfg['PolicyTypes'] CheckingFreqs = CS.getTypedDictRootedAt("CheckingFreqs") ############################################################################# # Web views ############################################################################# views_panels = { 'Site': [ 'Site_Panel', 'Service_Computing_Panel', 'Service_Storage_Panel', 'Service_VOMS_Panel', 'Service_VO-BOX_Panel' ], 'Resource': ['Resource_Panel'], 'StorageElement': ['SE_Panel']
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