def __init__(self): """ Constructor, initializes the rssClient. """ self.log = gLogger.getSubLogger(self.__class__.__name__) self.rssConfig = RssConfiguration() self.__opHelper = Operations() self.rssFlag = ResourceStatus().rssFlag self.rsClient = ResourceStatusClient() cacheLifeTime = int(self.rssConfig.getConfigCache()) # RSSCache only affects the calls directed to RSS, if using the CS it is not used. self.rssCache = RSSCache(cacheLifeTime, self.__updateRssCache)
def __init__( self ): """ Constructor, initializes the rssClient. """ self.log = gLogger.getSubLogger( self.__class__.__name__ ) self.rssConfig = RssConfiguration() self.__opHelper = Operations() self.rssClient = None # We can set CacheLifetime and CacheHistory from CS, so that we can tune them. cacheLifeTime = int( self.rssConfig.getConfigCache() ) # RSSCache only affects the calls directed to RSS, if using the CS it is not # used. self.seCache = RSSCache( 'StorageElement', cacheLifeTime, self.__updateSECache )
def __init__( self, rssFlag = None ): """ Constructor, initializes the rssClient. """ self.log = gLogger.getSubLogger( self.__class__.__name__ ) self.rssConfig = RssConfiguration() self.__opHelper = Operations() self.rssClient = ResourceStatusClient() self.rssFlag = rssFlag if rssFlag is None: self.rssFlag = self.__getMode() # We can set CacheLifetime and CacheHistory from CS, so that we can tune them. cacheLifeTime = int( self.rssConfig.getConfigCache() ) # RSSCache only affects the calls directed to RSS, if using the CS it is not used. self.rssCache = RSSCache( cacheLifeTime, self.__updateRssCache )
def __init__(self, rssFlag=None): """ Constructor, initializes the rssClient. """ self.log = gLogger.getSubLogger(self.__class__.__name__) self.rssConfig = RssConfiguration() self.__opHelper = Operations() self.rssClient = ResourceStatusClient() self.rssFlag = rssFlag if rssFlag is None: self.rssFlag = self.__getMode() # We can set CacheLifetime and CacheHistory from CS, so that we can tune them. cacheLifeTime = int(self.rssConfig.getConfigCache()) # RSSCache only affects the calls directed to RSS, if using the CS it is not used. self.rssCache = RSSCache(cacheLifeTime, self.__updateRssCache)
class ResourceStatus( object ): """ ResourceStatus helper that connects to CS if RSS flag is not Active. It keeps the connection to the db / server as an object member, to avoid creating a new one massively. """ __metaclass__ = DIRACSingleton def __init__( self ): """ Constructor, initializes the rssClient. """ self.log = gLogger.getSubLogger( self.__class__.__name__ ) self.rssConfig = RssConfiguration() self.__opHelper = Operations() self.rssClient = None self.infoGetter = InfoGetter() # We can set CacheLifetime and CacheHistory from CS, so that we can tune them. cacheLifeTime = int( self.rssConfig.getConfigCache() ) # RSSCache only affects the calls directed to RSS, if using the CS it is not # used. self.seCache = RSSCache( 'StorageElement', cacheLifeTime, self.__updateSECache ) def getStorageElementStatus( self, elementName, statusType = None, default = None ): """ Helper with dual access, tries to get information from the RSS for the given StorageElement, otherwise, it gets it from the CS. example: >>> getStorageElementStatus( 'CERN-USER', 'ReadAccess' ) S_OK( { 'CERN-USER' : { 'ReadAccess': 'Active' } } ) >>> getStorageElementStatus( 'CERN-USER', 'Write' ) S_OK( { 'CERN-USER' : {'ReadAccess': 'Active', 'WriteAccess': 'Active', 'CheckAccess': 'Banned', 'RemoveAccess': 'Banned'}} ) >>> getStorageElementStatus( 'CERN-USER', 'ThisIsAWrongStatusType' ) S_ERROR( xyz.. ) >>> getStorageElementStatus( 'CERN-USER', 'ThisIsAWrongStatusType', 'Unknown' ) S_OK( 'Unknown' ) """ if self.__getMode(): # We do not apply defaults. If is not on the cache, S_ERROR is returned. return self.__getRSSStorageElementStatus( elementName, statusType ) else: return self.__getCSStorageElementStatus( elementName, statusType, default ) def setStorageElementStatus( self, elementName, statusType, status, reason = None, tokenOwner = None ): """ Helper with dual access, tries set information in RSS and in CS. example: >>> getStorageElementStatus( 'CERN-USER', 'ReadAccess' ) S_OK( { 'ReadAccess': 'Active' } ) >>> getStorageElementStatus( 'CERN-USER', 'Write' ) S_OK( {'ReadAccess': 'Active', 'WriteAccess': 'Active', 'CheckAccess': 'Banned', 'RemoveAccess': 'Banned'} ) >>> getStorageElementStatus( 'CERN-USER', 'ThisIsAWrongStatusType' ) S_ERROR( xyz.. ) >>> getStorageElementStatus( 'CERN-USER', 'ThisIsAWrongStatusType', 'Unknown' ) S_OK( 'Unknown' ) """ if self.__getMode(): return self.__setRSSStorageElementStatus( elementName, statusType, status, reason, tokenOwner ) else: return self.__setCSStorageElementStatus( elementName, statusType, status ) ################################################################################ def __updateSECache( self ): """ Method used to update the StorageElementCache. It will try 5 times to contact the RSS before giving up """ meta = { 'columns' : [ 'Name', 'StatusType', 'Status' ] } for ti in range( 5 ): rawCache = self.rssClient.selectStatusElement( 'Resource', 'Status', elementType = 'StorageElement', meta = meta ) if rawCache['OK']: break self.log.warn( "Can't get SE status", rawCache['Message'] + "; trial %d" % ti ) sleep( math.pow( ti, 2 ) ) self.rssClient = ResourceStatusClient() if not rawCache[ 'OK' ]: return rawCache return S_OK( getCacheDictFromRawData( rawCache[ 'Value' ] ) ) ################################################################################ def __getRSSStorageElementStatus( self, elementName, statusType ): """ Gets from the cache or the RSS the StorageElements status. The cache is a copy of the DB table. If it is not on the cache, most likely is not going to be on the DB. There is one exception: item just added to the CS, e.g. new StorageElement. The period between it is added to the DB and the changes are propagated to the cache will be inconsisten, but not dangerous. Just wait <cacheLifeTime> minutes. """ cacheMatch = self.seCache.match( elementName, statusType ) self.log.debug( '__getRSSStorageElementStatus' ) self.log.debug( cacheMatch ) return cacheMatch def __getCSStorageElementStatus( self, elementName, statusType, default ): """ Gets from the CS the StorageElements status """ cs_path = "/Resources/StorageElements" if not isinstance( elementName, list ): elementName = [ elementName ] statuses = self.rssConfig.getConfigStatusType( 'StorageElement' ) result = {} for element in elementName: if statusType is not None: # Added Active by default res = gConfig.getValue( "%s/%s/%s" % ( cs_path, element, statusType ), 'Active' ) result[element] = {statusType: res} else: res = gConfig.getOptionsDict( "%s/%s" % ( cs_path, element ) ) if res[ 'OK' ] and res[ 'Value' ]: elementStatuses = {} for elementStatusType, value in res[ 'Value' ].items(): if elementStatusType in statuses: elementStatuses[ elementStatusType ] = value # If there is no status defined in the CS, we add by default Read and # Write as Active. if elementStatuses == {}: elementStatuses = { 'ReadAccess' : 'Active', 'WriteAccess' : 'Active' } result[ element ] = elementStatuses if result: return S_OK( result ) if default is not None: # sec check if statusType is None: statusType = 'none' defList = [ [ el, statusType, default ] for el in elementName ] return S_OK( getDictFromList( defList ) ) _msg = "StorageElement '%s', with statusType '%s' is unknown for CS." return S_ERROR( _msg % ( elementName, statusType ) ) def __setRSSStorageElementStatus( self, elementName, statusType, status, reason, tokenOwner ): """ Sets on the RSS the StorageElements status """ expiration = datetime.datetime.utcnow() + datetime.timedelta( days = 1 ) self.seCache.acquireLock() try: res = self.rssClient.modifyStatusElement( 'Resource', 'Status', name = elementName, statusType = statusType, status = status, reason = reason, tokenOwner = tokenOwner, tokenExpiration = expiration ) if res[ 'OK' ]: self.seCache.refreshCache() if not res[ 'OK' ]: _msg = 'Error updating StorageElement (%s,%s,%s)' % ( elementName, statusType, status ) gLogger.warn( 'RSS: %s' % _msg ) return res finally: # Release lock, no matter what. self.seCache.releaseLock() def __setCSStorageElementStatus( self, elementName, statusType, status ): """ Sets on the CS the StorageElements status """ statuses = self.rssConfig.getConfigStatusType( 'StorageElement' ) if not statusType in statuses: gLogger.error( "%s is not a valid statusType" % statusType ) return S_ERROR( "%s is not a valid statusType: %s" % ( statusType, statuses ) ) csAPI = CSAPI() cs_path = "/Resources/StorageElements" csAPI.setOption( "%s/%s/%s" % ( cs_path, elementName, statusType ), status ) res = csAPI.commitChanges() if not res[ 'OK' ]: gLogger.warn( 'CS: %s' % res[ 'Message' ] ) return res def __getMode( self ): """ Get's flag defined ( or not ) on the RSSConfiguration. If defined as 1, we use RSS, if not, we use CS. """ res = self.rssConfig.getConfigState() if res == 'Active': if self.rssClient is None: self.rssClient = ResourceStatusClient() return True self.rssClient = None return False def isStorageElementAlwaysBanned( self, seName, statusType ): """ Checks if the AlwaysBanned policy is applied to the SE given as parameter :param seName : string, name of the SE :param statusType : ReadAcces, WriteAccess, RemoveAccess, CheckAccess :returns S_OK(True/False) """ res = self.infoGetter.getPoliciesThatApply( {'name' : seName, 'statusType' : statusType} ) if not res['OK']: self.log.error( "isStorageElementAlwaysBanned: unable to get the information", res['Message'] ) return res isAlwaysBanned = 'AlwaysBanned' in [policy['type'] for policy in res['Value']] return S_OK( isAlwaysBanned )
class ResourceStatus( object ): """ ResourceStatus helper that connects to CS if RSS flag is not Active. It keeps the connection to the db / server as an object member, to avoid creating a new one massively. """ __metaclass__ = DIRACSingleton def __init__( self, rssFlag = None ): """ Constructor, initializes the rssClient. """ self.log = gLogger.getSubLogger( self.__class__.__name__ ) self.rssConfig = RssConfiguration() self.__opHelper = Operations() self.rssClient = ResourceStatusClient() self.rssFlag = rssFlag if rssFlag is None: self.rssFlag = self.__getMode() # We can set CacheLifetime and CacheHistory from CS, so that we can tune them. cacheLifeTime = int( self.rssConfig.getConfigCache() ) # RSSCache only affects the calls directed to RSS, if using the CS it is not used. self.rssCache = RSSCache( cacheLifeTime, self.__updateRssCache ) def getElementStatus( self, elementName, elementType, statusType = None, default = None ): """ Helper function, tries to get information from the RSS for the given Element, otherwise, it gets it from the CS. :param elementName: name of the element :type elementName: str :param elementType: type of the element (StorageElement, ComputingElement, FTS, Catalog) :type elementType: str :param statusType: type of the status (meaningful only when elementType==StorageElement) :type statusType: None, str, list :param default: defult value (meaningful only when rss is InActive) :type default: str :return: S_OK/S_ERROR :rtype: dict :Example: >>> getElementStatus('CE42', 'ComputingElement') S_OK( { 'CE42': { 'all': 'Active' } } } ) >>> getElementStatus('SE1', 'StorageElement', 'ReadAccess') S_OK( { 'SE1': { 'ReadAccess': 'Banned' } } } ) >>> getElementStatus('SE1', 'ThisIsAWrongElementType', 'ReadAccess') S_ERROR( xyz.. ) >>> getElementStatus('ThisIsAWrongName', 'StorageElement', 'WriteAccess') S_ERROR( xyz.. ) >>> getElementStatus('A_file_catalog', 'FileCatalog') S_OK( { 'A_file_catalog': { 'all': 'Active' } } } ) >>> getElementStatus('SE1', 'StorageElement', ['ReadAccess', 'WriteAccess']) S_OK( { 'SE1': { 'ReadAccess': 'Banned' , 'WriteAccess': 'Active'} } } ) >>> getElementStatus('SE1', 'StorageElement') S_OK( { 'SE1': { 'ReadAccess': 'Probing' , 'WriteAccess': 'Active', 'CheckAccess': 'Degraded', 'RemoveAccess': 'Banned'} } } ) """ allowedParameters = ["StorageElement", "ComputingElement", "FTS", "Catalog"] if elementType not in allowedParameters: return S_ERROR("%s in not in the list of the allowed parameters: %s" % (elementType, allowedParameters)) # Apply defaults if not statusType: if elementType == "StorageElement": statusType = ['ReadAccess', 'WriteAccess', 'CheckAccess', 'RemoveAccess'] elif elementType == "ComputingElement": statusType = ['all'] elif elementType == "FTS": statusType = ['all'] elif elementType == "Catalog": statusType = ['all'] if self.rssFlag: return self.__getRSSElementStatus( elementName, elementType, statusType ) else: return self.__getCSElementStatus( elementName, elementType, statusType, default ) def setElementStatus( self, elementName, elementType, statusType, status, reason = None, tokenOwner = None ): """ Tries set information in RSS and in CS. :param elementName: name of the element :type elementName: str :param elementType: type of the element (StorageElement, ComputingElement, FTS, Catalog) :type elementType: str :param statusType: type of the status (meaningful only when elementType==StorageElement) :type statusType: str :param reason: reason for setting the status :type reason: str :param tokenOwner: owner of the token (meaningful only when rss is Active) :type tokenOwner: str :return: S_OK/S_ERROR :rtype: dict :Example: >>> setElementStatus('CE42', 'ComputingElement', 'all', 'Active') S_OK( xyz.. ) >>> setElementStatus('SE1', 'StorageElement', 'ReadAccess', 'Banned') S_OK( xyz.. ) """ if self.rssFlag: return self.__setRSSElementStatus( elementName, elementType, statusType, status, reason, tokenOwner ) else: return self.__setCSElementStatus( elementName, elementType, statusType, status ) ################################################################################ def __updateRssCache( self ): """ Method used to update the rssCache. It will try 5 times to contact the RSS before giving up """ meta = { 'columns' : [ 'Name', 'ElementType', 'StatusType', 'Status' ] } for ti in range( 5 ): rawCache = self.rssClient.selectStatusElement( 'Resource', 'Status', meta = meta ) if rawCache['OK']: break self.log.warn( "Can't get resource's status", rawCache['Message'] + "; trial %d" % ti ) sleep( math.pow( ti, 2 ) ) self.rssClient = ResourceStatusClient() if not rawCache[ 'OK' ]: return rawCache return S_OK( getCacheDictFromRawData( rawCache[ 'Value' ] ) ) ################################################################################ def __getRSSElementStatus( self, elementName, elementType, statusType ): """ Gets from the cache or the RSS the Elements status. The cache is a copy of the DB table. If it is not on the cache, most likely is not going to be on the DB. There is one exception: item just added to the CS, e.g. new Element. The period between it is added to the DB and the changes are propagated to the cache will be inconsistent, but not dangerous. Just wait <cacheLifeTime> minutes. :param elementName: name of the element :type elementName: str :param elementType: type of the element (StorageElement, ComputingElement, FTS, Catalog) :type elementType: str :param statusType: type of the status (meaningful only when elementType==StorageElement, otherwise it is 'all' or ['all']) :type statusType: str, list """ cacheMatch = self.rssCache.match( elementName, elementType, statusType ) self.log.debug( '__getRSSElementStatus' ) self.log.debug( cacheMatch ) return cacheMatch def __getCSElementStatus( self, elementName, elementType, statusType, default ): """ Gets from the CS the Element status :param elementName: name of the element :type elementName: str :param elementType: type of the element (StorageElement, ComputingElement, FTS, Catalog) :type elementType: str :param statusType: type of the status (meaningful only when elementType==StorageElement) :type statusType: str, list :param default: defult value :type default: None, str """ # DIRAC doesn't store the status of ComputingElements nor FTS in the CS, so here we can just return 'Active' if elementType in ('ComputingElement', 'FTS'): return S_OK( { elementName: { 'all': 'Active'} } ) # If we are here it is because elementType is either 'StorageElement' or 'Catalog' if elementType == 'StorageElement': cs_path = "/Resources/StorageElements" elif elementType == 'Catalog': cs_path = "/Resources/FileCatalogs" statusType = ['Status'] if not isinstance( elementName, list ): elementName = [ elementName ] if not isinstance( statusType, list ): statusType = [ statusType ] result = {} for element in elementName: for sType in statusType: # Look in standard location, 'Active' by default res = gConfig.getValue( "%s/%s/%s" % ( cs_path, element, sType ), 'Active' ) result.setdefault( element, {} )[sType] = res if result: return S_OK( result ) if default is not None: defList = [ [ el, statusType, default ] for el in elementName ] return S_OK( getDictFromList( defList ) ) _msg = "Element '%s', with statusType '%s' is unknown for CS." return S_ERROR( DErrno.ERESUNK, _msg % ( elementName, statusType ) ) def __setRSSElementStatus( self, elementName, elementType, statusType, status, reason, tokenOwner ): """ Sets on the RSS the Elements status """ expiration = datetime.utcnow() + timedelta( days = 1 ) self.rssCache.acquireLock() try: res = self.rssClient.addOrModifyStatusElement( 'Resource', 'Status', name = elementName, elementType = elementType, status = status, statusType = statusType, reason = reason, tokenOwner = tokenOwner, tokenExpiration = expiration ) if res[ 'OK' ]: self.rssCache.refreshCache() if not res[ 'OK' ]: _msg = 'Error updating Element (%s,%s,%s)' % ( elementName, statusType, status ) gLogger.warn( 'RSS: %s' % _msg ) return res finally: # Release lock, no matter what. self.rssCache.releaseLock() def __setCSElementStatus( self, elementName, elementType, statusType, status ): """ Sets on the CS the Elements status """ # DIRAC doesn't store the status of ComputingElements nor FTS in the CS, so here we can just do nothing if elementType in ('ComputingElement', 'FTS'): return S_OK() # If we are here it is because elementType is either 'StorageElement' or 'Catalog' statuses = self.rssConfig.getConfigStatusType( elementType ) if statusType not in statuses: gLogger.error( "%s is not a valid statusType" % statusType ) return S_ERROR( "%s is not a valid statusType: %s" % ( statusType, statuses ) ) if elementType == 'StorageElement': cs_path = "/Resources/StorageElements" elif elementType == 'Catalog': cs_path = "/Resources/FileCatalogs" #FIXME: This a probably outdated location (new one is in /Operations/[]/Services/Catalogs) # but needs to be VO-aware statusType = 'Status' csAPI = CSAPI() csAPI.setOption( "%s/%s/%s/%s" % ( cs_path, elementName, elementType, statusType ), status ) res = csAPI.commitChanges() if not res[ 'OK' ]: gLogger.warn( 'CS: %s' % res[ 'Message' ] ) return res def __getMode( self ): """ Get's flag defined ( or not ) on the RSSConfiguration. If defined as 1, we use RSS, if not, we use CS. """ res = self.rssConfig.getConfigState() if res == 'Active': if self.rssClient is None: self.rssClient = ResourceStatusClient() return True self.rssClient = None return False def isStorageElementAlwaysBanned( self, seName, statusType ): """ Checks if the AlwaysBanned policy is applied to the SE given as parameter :param seName : string, name of the SE :param statusType : ReadAcces, WriteAccess, RemoveAccess, CheckAccess :returns: S_OK(True/False) """ res = getPoliciesThatApply( {'name' : seName, 'statusType' : statusType} ) if not res['OK']: self.log.error( "isStorageElementAlwaysBanned: unable to get the information", res['Message'] ) return res isAlwaysBanned = 'AlwaysBanned' in [policy['type'] for policy in res['Value']] return S_OK( isAlwaysBanned )
class ResourceStatus(object): """ ResourceStatus helper that connects to CS if RSS flag is not Active. It keeps the connection to the db / server as an object member, to avoid creating a new one massively. """ __metaclass__ = DIRACSingleton def __init__(self): """ Constructor, initializes the rssClient. """ self.log = gLogger.getSubLogger(self.__class__.__name__) self.rssConfig = RssConfiguration() self.__opHelper = Operations() self.rssClient = None # We can set CacheLifetime and CacheHistory from CS, so that we can tune them. cacheLifeTime = int(self.rssConfig.getConfigCache()) # RSSCache only affects the calls directed to RSS, if using the CS it is not # used. self.seCache = RSSCache('StorageElement', cacheLifeTime, self.__updateSECache) def getStorageElementStatus(self, elementName, statusType=None, default=None): """ Helper with dual access, tries to get information from the RSS for the given StorageElement, otherwise, it gets it from the CS. example: >>> getStorageElementStatus( 'CERN-USER', 'ReadAccess' ) S_OK( { 'CERN-USER' : { 'ReadAccess': 'Active' } } ) >>> getStorageElementStatus( 'CERN-USER', 'Write' ) S_OK( { 'CERN-USER' : {'ReadAccess': 'Active', 'WriteAccess': 'Active', 'CheckAccess': 'Banned', 'RemoveAccess': 'Banned'}} ) >>> getStorageElementStatus( 'CERN-USER', 'ThisIsAWrongStatusType' ) S_ERROR( xyz.. ) >>> getStorageElementStatus( 'CERN-USER', 'ThisIsAWrongStatusType', 'Unknown' ) S_OK( 'Unknown' ) """ if self.__getMode(): # We do not apply defaults. If is not on the cache, S_ERROR is returned. return self.__getRSSStorageElementStatus(elementName, statusType) else: return self.__getCSStorageElementStatus(elementName, statusType, default) def setStorageElementStatus(self, elementName, statusType, status, reason=None, tokenOwner=None): """ Helper with dual access, tries set information in RSS and in CS. example: >>> getStorageElementStatus( 'CERN-USER', 'ReadAccess' ) S_OK( { 'ReadAccess': 'Active' } ) >>> getStorageElementStatus( 'CERN-USER', 'Write' ) S_OK( {'ReadAccess': 'Active', 'WriteAccess': 'Active', 'CheckAccess': 'Banned', 'RemoveAccess': 'Banned'} ) >>> getStorageElementStatus( 'CERN-USER', 'ThisIsAWrongStatusType' ) S_ERROR( xyz.. ) >>> getStorageElementStatus( 'CERN-USER', 'ThisIsAWrongStatusType', 'Unknown' ) S_OK( 'Unknown' ) """ if self.__getMode(): return self.__setRSSStorageElementStatus(elementName, statusType, status, reason, tokenOwner) else: return self.__setCSStorageElementStatus(elementName, statusType, status) ################################################################################ def __updateSECache(self): """ Method used to update the StorageElementCache. """ meta = {'columns': ['Name', 'StatusType', 'Status']} rawCache = self.rssClient.selectStatusElement( 'Resource', 'Status', elementType='StorageElement', meta=meta) if not rawCache['OK']: return rawCache return S_OK(getCacheDictFromRawData(rawCache['Value'])) ################################################################################ def __getRSSStorageElementStatus(self, elementName, statusType): """ Gets from the cache or the RSS the StorageElements status. The cache is a copy of the DB table. If it is not on the cache, most likely is not going to be on the DB. There is one exception: item just added to the CS, e.g. new StorageElement. The period between it is added to the DB and the changes are propagated to the cache will be inconsisten, but not dangerous. Just wait <cacheLifeTime> minutes. """ cacheMatch = self.seCache.match(elementName, statusType) self.log.debug('__getRSSStorageElementStatus') self.log.debug(cacheMatch) return cacheMatch def __getCSStorageElementStatus(self, elementName, statusType, default): """ Gets from the CS the StorageElements status """ cs_path = "/Resources/StorageElements" if not isinstance(elementName, list): elementName = [elementName] statuses = self.rssConfig.getConfigStatusType('StorageElement') result = {} for element in elementName: if statusType is not None: # Added Active by default res = gConfig.getOption( "%s/%s/%s" % (cs_path, element, statusType), 'Active') if res['OK'] and res['Value']: result[element] = {statusType: res['Value']} else: res = gConfig.getOptionsDict("%s/%s" % (cs_path, element)) if res['OK'] and res['Value']: elementStatuses = {} for elementStatusType, value in res['Value'].items(): if elementStatusType in statuses: elementStatuses[elementStatusType] = value # If there is no status defined in the CS, we add by default Read and # Write as Active. if elementStatuses == {}: elementStatuses = { 'ReadAccess': 'Active', 'WriteAccess': 'Active' } result[element] = elementStatuses if result: return S_OK(result) if default is not None: # sec check if statusType is None: statusType = 'none' defList = [[el, statusType, default] for el in elementName] return S_OK(getDictFromList(defList)) _msg = "StorageElement '%s', with statusType '%s' is unknown for CS." return S_ERROR(_msg % (elementName, statusType)) def __setRSSStorageElementStatus(self, elementName, statusType, status, reason, tokenOwner): """ Sets on the RSS the StorageElements status """ expiration = datetime.datetime.utcnow() + datetime.timedelta(days=1) self.seCache.acquireLock() try: res = self.rssClient.modifyStatusElement( 'Resource', 'Status', name=elementName, statusType=statusType, status=status, reason=reason, tokenOwner=tokenOwner, tokenExpiration=expiration) if res['OK']: self.seCache.refreshCache() if not res['OK']: _msg = 'Error updating StorageElement (%s,%s,%s)' % ( elementName, statusType, status) gLogger.warn('RSS: %s' % _msg) return res finally: # Release lock, no matter what. self.seCache.releaseLock() def __setCSStorageElementStatus(self, elementName, statusType, status): """ Sets on the CS the StorageElements status """ statuses = self.rssConfig.getConfigStatusType('StorageElement') if not statusType in statuses: gLogger.error("%s is not a valid statusType" % statusType) return S_ERROR("%s is not a valid statusType: %s" % (statusType, statuses)) csAPI = CSAPI() cs_path = "/Resources/StorageElements" csAPI.setOption("%s/%s/%s" % (cs_path, elementName, statusType), status) res = csAPI.commitChanges() if not res['OK']: gLogger.warn('CS: %s' % res['Message']) return res def __getMode(self): """ Get's flag defined ( or not ) on the RSSConfiguration. If defined as 1, we use RSS, if not, we use CS. """ res = self.rssConfig.getConfigState() if res == 'Active': if self.rssClient is None: self.rssClient = ResourceStatusClient() return True self.rssClient = None return False
class SiteStatus(object): """ RSS helper to interact with the 'Site' family on the DB. It provides the most demanded functions and a cache to avoid hitting the server too often. It provides four methods to interact with the site statuses: * getSiteStatuses * isUsableSite * getUsableSites * getSites """ __metaclass__ = DIRACSingleton def __init__(self): """ Constructor, initializes the rssClient. """ self.log = gLogger.getSubLogger(self.__class__.__name__) self.rssConfig = RssConfiguration() self.__opHelper = Operations() self.rssFlag = ResourceStatus().rssFlag self.rsClient = ResourceStatusClient() cacheLifeTime = int(self.rssConfig.getConfigCache()) # RSSCache only affects the calls directed to RSS, if using the CS it is not used. self.rssCache = RSSCache(cacheLifeTime, self.__updateRssCache) def __updateRssCache(self): """ Method used to update the rssCache. It will try 5 times to contact the RSS before giving up """ meta = {'columns': ['Name', 'Status']} for ti in xrange(5): rawCache = self.rsClient.selectStatusElement('Site', 'Status', meta=meta) if rawCache['OK']: break self.log.warn("Can't get resource's status", rawCache['Message'] + "; trial %d" % ti) sleep(math.pow(ti, 2)) self.rsClient = ResourceStatusClient() if not rawCache['OK']: return rawCache return S_OK(getCacheDictFromRawData(rawCache['Value'])) def getSiteStatuses(self, siteNames=None): """ Method that queries the database for status of the sites in a given list. A single string site name may also be provides as "siteNames" If the input is None, it is interpreted as * ( all ). If match is positive, the output looks like: { 'test1.test1.org': 'Active', 'test2.test2.org': 'Banned', } examples >>> siteStatus.getSiteStatuses( ['test1.test1.uk', 'test2.test2.net', 'test3.test3.org'] ) S_OK( { 'test1.test1.org': 'Active', 'test2.test2.net': 'Banned', 'test3.test3.org': 'Active' } ) >>> siteStatus.getSiteStatuses( 'NotExists') S_ERROR( ... )) >>> siteStatus.getSiteStatuses( None ) S_OK( { 'test1.test1.org': 'Active', 'test2.test2.net': 'Banned', }, ... } ) :Parameters: **siteNames** - `list` or `str` name(s) of the sites to be matched :return: S_OK() || S_ERROR() """ if self.rssFlag: return self.__getRSSSiteStatus(siteNames) else: siteStatusDict = {} wmsAdmin = RPCClient('WorkloadManagement/WMSAdministrator') if siteNames: if isinstance(siteNames, basestring): siteNames = [siteNames] for siteName in siteNames: result = wmsAdmin.getSiteMaskStatus(siteName) if not result['OK']: return result else: siteStatusDict[siteName] = result['Value'] else: result = wmsAdmin.getSiteMaskStatus() if not result['OK']: return result else: siteStatusDict = result['Value'] return S_OK(siteStatusDict) def __getRSSSiteStatus(self, siteName=None): """ Gets from the cache or the RSS the Sites status. The cache is a copy of the DB table. If it is not on the cache, most likely is not going to be on the DB. There is one exception: item just added to the CS, e.g. new Element. The period between it is added to the DB and the changes are propagated to the cache will be inconsistent, but not dangerous. Just wait <cacheLifeTime> minutes. :param siteName: name of the site :type siteName: str :return: dict """ cacheMatch = self.rssCache.match(siteName, '', '') self.log.debug('__getRSSSiteStatus') self.log.debug(cacheMatch) return cacheMatch def getUsableSites(self, siteNames=None): """ Returns all sites that are usable if their statusType is either Active or Degraded; in a list. examples >>> siteStatus.getUsableSites( ['test1.test1.uk', 'test2.test2.net', 'test3.test3.org'] ) S_OK( ['test1.test1.uk', 'test3.test3.org'] ) >>> siteStatus.getUsableSites( None ) S_OK( ['test1.test1.uk', 'test3.test3.org', 'test4.test4.org', 'test5.test5.org', ...] ) >>> siteStatus.getUsableSites( 'NotExists' ) S_ERROR( ... ) :Parameters: **siteNames** - `List` or `str` name(s) of the sites to be matched :return: S_OK() || S_ERROR() """ siteStatusDictRes = self.getSiteStatuses(siteNames) if not siteStatusDictRes['OK']: return siteStatusDictRes siteStatusList = [ x[0] for x in siteStatusDictRes['Value'].iteritems() if x[1] in ['Active', 'Degraded'] ] return S_OK(siteStatusList) def getSites(self, siteState='Active'): """ By default, it gets the currently active site list examples >>> siteStatus.getSites() S_OK( ['test1.test1.uk', 'test3.test3.org'] ) >>> siteStatus.getSites( 'Active' ) S_OK( ['test1.test1.uk', 'test3.test3.org'] ) >>> siteStatus.getSites( 'Banned' ) S_OK( ['test0.test0.uk', ... ] ) >>> siteStatus.getSites( 'All' ) S_OK( ['test1.test1.uk', 'test3.test3.org', 'test4.test4.org', 'test5.test5.org'...] ) >>> siteStatus.getSites( None ) S_ERROR( ... ) :Parameters: **siteState** - `String` state of the sites to be matched :return: S_OK() || S_ERROR() """ if not siteState: return S_ERROR(DErrno.ERESUNK, 'siteState parameter is empty') siteStatusDictRes = self.getSiteStatuses() if not siteStatusDictRes['OK']: return siteStatusDictRes if siteState.capitalize() == 'All': # if no siteState is set return everything siteList = list(siteStatusDictRes['Value']) else: # fix case sensitive string siteState = siteState.capitalize() allowedStateList = [ 'Active', 'Banned', 'Degraded', 'Probing', 'Error', 'Unknown' ] if siteState not in allowedStateList: return S_ERROR(errno.EINVAL, 'Not a valid status, parameter rejected') siteList = [ x[0] for x in siteStatusDictRes['Value'].iteritems() if x[1] == siteState ] return S_OK(siteList) def setSiteStatus(self, site, status, comment='No comment'): """ Set the status of a site in the 'SiteStatus' table of RSS examples >>> siteStatus.banSite( 'site1.test.test' ) S_OK() >>> siteStatus.banSite( None ) S_ERROR( ... ) :Parameters: **site** - `String` the site that is going to be banned **comment** - `String` reason for banning :return: S_OK() || S_ERROR() """ if not status: return S_ERROR(DErrno.ERESUNK, 'status parameter is empty') # fix case sensitive string status = status.capitalize() allowedStateList = [ 'Active', 'Banned', 'Degraded', 'Probing', 'Error', 'Unknown' ] if status not in allowedStateList: return S_ERROR(errno.EINVAL, 'Not a valid status, parameter rejected') if self.rssFlag: result = getProxyInfo() if result['OK']: tokenOwner = result['Value']['username'] else: return S_ERROR("Unable to get user proxy info %s " % result['Message']) tokenExpiration = datetime.utcnow() + timedelta(days=1) self.rssCache.acquireLock() try: result = self.rsClient.modifyStatusElement( 'Site', 'Status', status=status, name=site, tokenExpiration=tokenExpiration, reason=comment, tokenOwner=tokenOwner) if result['OK']: self.rssCache.refreshCache() else: _msg = 'Error updating status of site %s to %s' % (site, status) gLogger.warn('RSS: %s' % _msg) # Release lock, no matter what. finally: self.rssCache.releaseLock() else: if status in ['Active', 'Degraded']: result = RPCClient( 'WorkloadManagement/WMSAdministrator').allowSite() else: result = RPCClient( 'WorkloadManagement/WMSAdministrator').banSite() return result
class SiteStatus(object): """ RSS helper to interact with the 'Site' family on the DB. It provides the most demanded functions and a cache to avoid hitting the server too often. It provides four methods to interact with the site statuses: * getSiteStatuses * isUsableSite * getUsableSites * getSites """ __metaclass__ = DIRACSingleton def __init__(self): """ Constructor, initializes the rssClient. """ self.log = gLogger.getSubLogger(self.__class__.__name__) self.rssConfig = RssConfiguration() self.__opHelper = Operations() self.rssFlag = ResourceStatus().rssFlag self.rsClient = ResourceStatusClient() # We can set CacheLifetime and CacheHistory from CS, so that we can tune them. cacheLifeTime = int(self.rssConfig.getConfigCache()) # RSSCache only affects the calls directed to RSS, if using the CS it is not used. self.rssCache = RSSCache(cacheLifeTime, self.__updateRssCache) def __updateRssCache(self): """ Method used to update the rssCache. It will try 5 times to contact the RSS before giving up """ meta = {'columns': ['Name', 'Status']} for ti in xrange(5): rawCache = self.rsClient.selectStatusElement('Site', 'Status', meta=meta) if rawCache['OK']: break self.log.warn("Can't get resource's status", rawCache['Message'] + "; trial %d" % ti) sleep(math.pow(ti, 2)) self.rsClient = ResourceStatusClient() if not rawCache['OK']: return rawCache return S_OK(getCacheDictFromRawData(rawCache['Value'])) def getSiteStatuses(self, siteNames=None): """ Method that queries the database for status of the sites in a given list. A single string site name may also be provides as "siteNames" If the input is None, it is interpreted as * ( all ). If match is positive, the output looks like: { 'test1.test1.org': 'Active', 'test2.test2.org': 'Banned', } examples >>> siteStatus.getSiteStatuses( ['test1.test1.uk', 'test2.test2.net', 'test3.test3.org'] ) S_OK( { 'test1.test1.org': 'Active', 'test2.test2.net': 'Banned', 'test3.test3.org': 'Active' } ) >>> siteStatus.getSiteStatuses( 'NotExists') S_ERROR( ... )) >>> siteStatus.getSiteStatuses( None ) S_OK( { 'test1.test1.org': 'Active', 'test2.test2.net': 'Banned', }, ... } ) :Parameters: **siteNames** - `list` or `str` name(s) of the sites to be matched :return: S_OK() || S_ERROR() """ if self.rssFlag: return self.__getRSSSiteStatus(siteNames) else: siteStatusDict = {} wmsAdmin = RPCClient('WorkloadManagement/WMSAdministrator') if siteNames: if isinstance(siteNames, basestring): siteNames = [siteNames] for siteName in siteNames: result = wmsAdmin.getSiteMaskStatus(siteName) if not result['OK']: return result else: siteStatusDict[siteName] = result['Value'] else: result = wmsAdmin.getSiteMaskStatus() if not result['OK']: return result else: siteStatusDict = result['Value'] return S_OK(siteStatusDict) def __getRSSSiteStatus(self, siteName=None): """ Gets from the cache or the RSS the Sites status. The cache is a copy of the DB table. If it is not on the cache, most likely is not going to be on the DB. There is one exception: item just added to the CS, e.g. new Element. The period between it is added to the DB and the changes are propagated to the cache will be inconsistent, but not dangerous. Just wait <cacheLifeTime> minutes. :param siteName: name of the site :type siteName: str :return: dict """ cacheMatch = self.rssCache.match(siteName, '', '') self.log.debug('__getRSSSiteStatus') self.log.debug(cacheMatch) return cacheMatch def getUsableSites(self, siteNames=None): """ Returns all sites that are usable if their statusType is either Active or Degraded; in a list. examples >>> siteStatus.getUsableSites( ['test1.test1.uk', 'test2.test2.net', 'test3.test3.org'] ) S_OK( ['test1.test1.uk', 'test3.test3.org'] ) >>> siteStatus.getUsableSites( None ) S_OK( ['test1.test1.uk', 'test3.test3.org', 'test4.test4.org', 'test5.test5.org', ...] ) >>> siteStatus.getUsableSites( 'NotExists' ) S_ERROR( ... ) :Parameters: **siteNames** - `List` or `str` name(s) of the sites to be matched :return: S_OK() || S_ERROR() """ siteStatusDictRes = self.getSiteStatuses(siteNames) if not siteStatusDictRes['OK']: return siteStatusDictRes siteStatusList = [x[0] for x in siteStatusDictRes['Value'].iteritems() if x[1] in ['Active', 'Degraded']] return S_OK(siteStatusList) def getSites(self, siteState='Active'): """ By default, it gets the currently active site list examples >>> siteStatus.getSites() S_OK( ['test1.test1.uk', 'test3.test3.org'] ) >>> siteStatus.getSites( 'Active' ) S_OK( ['test1.test1.uk', 'test3.test3.org'] ) >>> siteStatus.getSites( 'Banned' ) S_OK( ['test0.test0.uk', ... ] ) >>> siteStatus.getSites( 'All' ) S_OK( ['test1.test1.uk', 'test3.test3.org', 'test4.test4.org', 'test5.test5.org'...] ) >>> siteStatus.getSites( None ) S_ERROR( ... ) :Parameters: **siteState** - `String` state of the sites to be matched :return: S_OK() || S_ERROR() """ if not siteState: return S_ERROR(DErrno.ERESUNK, 'siteState parameter is empty') siteStatusDictRes = self.getSiteStatuses() if not siteStatusDictRes['OK']: return siteStatusDictRes if siteState.capitalize() == 'All': # if no siteState is set return everything siteList = list(siteStatusDictRes['Value']) else: # fix case sensitive string siteState = siteState.capitalize() allowedStateList = ['Active', 'Banned', 'Degraded', 'Probing', 'Error', 'Unknown'] if siteState not in allowedStateList: return S_ERROR(errno.EINVAL, 'Not a valid status, parameter rejected') siteList = [x[0] for x in siteStatusDictRes['Value'].iteritems() if x[1] == siteState] return S_OK(siteList) def setSiteStatus(self, site, status, comment='No comment'): """ Set the status of a site in the 'SiteStatus' table of RSS examples >>> siteStatus.banSite( 'site1.test.test' ) S_OK() >>> siteStatus.banSite( None ) S_ERROR( ... ) :Parameters: **site** - `String` the site that is going to be banned **comment** - `String` reason for banning :return: S_OK() || S_ERROR() """ if not status: return S_ERROR(DErrno.ERESUNK, 'status parameter is empty') # fix case sensitive string status = status.capitalize() allowedStateList = ['Active', 'Banned', 'Degraded', 'Probing', 'Error', 'Unknown'] if status not in allowedStateList: return S_ERROR(errno.EINVAL, 'Not a valid status, parameter rejected') if self.rssFlag: result = getProxyInfo() if result['OK']: tokenOwner = result['Value']['username'] else: return S_ERROR("Unable to get user proxy info %s " % result['Message']) tokenExpiration = datetime.utcnow() + timedelta(days=1) self.rssCache.acquireLock() try: result = self.rsClient.modifyStatusElement('Site', 'Status', status=status, name=site, tokenExpiration=tokenExpiration, reason=comment, tokenOwner=tokenOwner) if result['OK']: self.rssCache.refreshCache() else: _msg = 'Error updating status of site %s to %s' % (site, status) gLogger.warn('RSS: %s' % _msg) # Release lock, no matter what. finally: self.rssCache.releaseLock() else: if status in ['Active', 'Degraded']: result = RPCClient('WorkloadManagement/WMSAdministrator').allowSite() else: result = RPCClient('WorkloadManagement/WMSAdministrator').banSite() return result
class ResourceStatus(object): """ ResourceStatus helper that connects to CS if RSS flag is not Active. It keeps the connection to the db / server as an object member, to avoid creating a new one massively. """ __metaclass__ = DIRACSingleton def __init__(self, rssFlag=None): """ Constructor, initializes the rssClient. """ self.log = gLogger.getSubLogger(self.__class__.__name__) self.rssConfig = RssConfiguration() self.__opHelper = Operations() self.rssClient = ResourceStatusClient() self.rssFlag = rssFlag if rssFlag is None: self.rssFlag = self.__getMode() cacheLifeTime = int(self.rssConfig.getConfigCache()) # RSSCache only affects the calls directed to RSS, if using the CS it is not used. self.rssCache = RSSCache(cacheLifeTime, self.__updateRssCache) def getElementStatus(self, elementName, elementType, statusType=None, default=None): """ Helper function, tries to get information from the RSS for the given Element, otherwise, it gets it from the CS. :param elementName: name of the element or list of element names :type elementName: str, list :param elementType: type of the element (StorageElement, ComputingElement, FTS, Catalog) :type elementType: str :param statusType: type of the status (meaningful only when elementType==StorageElement) :type statusType: None, str, list :param default: defult value (meaningful only when rss is InActive) :type default: str :return: S_OK/S_ERROR :rtype: dict :Example: >>> getElementStatus('CE42', 'ComputingElement') S_OK( { 'CE42': { 'all': 'Active' } } } ) >>> getElementStatus('SE1', 'StorageElement', 'ReadAccess') S_OK( { 'SE1': { 'ReadAccess': 'Banned' } } } ) >>> getElementStatus('SE1', 'ThisIsAWrongElementType', 'ReadAccess') S_ERROR( xyz.. ) >>> getElementStatus('ThisIsAWrongName', 'StorageElement', 'WriteAccess') S_ERROR( xyz.. ) >>> getElementStatus('A_file_catalog', 'FileCatalog') S_OK( { 'A_file_catalog': { 'all': 'Active' } } } ) >>> getElementStatus('SE1', 'StorageElement', ['ReadAccess', 'WriteAccess']) S_OK( { 'SE1': { 'ReadAccess': 'Banned' , 'WriteAccess': 'Active'} } } ) >>> getElementStatus('SE1', 'StorageElement') S_OK( { 'SE1': { 'ReadAccess': 'Probing' , 'WriteAccess': 'Active', 'CheckAccess': 'Degraded', 'RemoveAccess': 'Banned'} } } ) >>> getElementStatus(['CE1', 'CE2'], 'ComputingElement') S_OK( {'CE1': {'all': 'Active'}, 'CE2': {'all': 'Probing'}}} """ allowedParameters = ["StorageElement", "ComputingElement", "FTS", "Catalog"] if elementType not in allowedParameters: return S_ERROR("%s in not in the list of the allowed parameters: %s" % (elementType, allowedParameters)) # Apply defaults if not statusType: if elementType == "StorageElement": statusType = ['ReadAccess', 'WriteAccess', 'CheckAccess', 'RemoveAccess'] elif elementType == "ComputingElement": statusType = ['all'] elif elementType == "FTS": statusType = ['all'] elif elementType == "Catalog": statusType = ['all'] if self.rssFlag: return self.__getRSSElementStatus(elementName, elementType, statusType) else: return self.__getCSElementStatus(elementName, elementType, statusType, default) def setElementStatus(self, elementName, elementType, statusType, status, reason=None, tokenOwner=None): """ Tries set information in RSS and in CS. :param elementName: name of the element :type elementName: str :param elementType: type of the element (StorageElement, ComputingElement, FTS, Catalog) :type elementType: str :param statusType: type of the status (meaningful only when elementType==StorageElement) :type statusType: str :param reason: reason for setting the status :type reason: str :param tokenOwner: owner of the token (meaningful only when rss is Active) :type tokenOwner: str :return: S_OK/S_ERROR :rtype: dict :Example: >>> setElementStatus('CE42', 'ComputingElement', 'all', 'Active') S_OK( xyz.. ) >>> setElementStatus('SE1', 'StorageElement', 'ReadAccess', 'Banned') S_OK( xyz.. ) """ if self.rssFlag: return self.__setRSSElementStatus(elementName, elementType, statusType, status, reason, tokenOwner) else: return self.__setCSElementStatus(elementName, elementType, statusType, status) ################################################################################ def __updateRssCache(self): """ Method used to update the rssCache. It will try 5 times to contact the RSS before giving up """ meta = {'columns': ['Name', 'ElementType', 'StatusType', 'Status']} for ti in range(5): rawCache = self.rssClient.selectStatusElement('Resource', 'Status', meta=meta) if rawCache['OK']: break self.log.warn("Can't get resource's status", rawCache['Message'] + "; trial %d" % ti) sleep(math.pow(ti, 2)) self.rssClient = ResourceStatusClient() if not rawCache['OK']: return rawCache return S_OK(getCacheDictFromRawData(rawCache['Value'])) ################################################################################ def __getRSSElementStatus(self, elementName, elementType, statusType): """ Gets from the cache or the RSS the Elements status. The cache is a copy of the DB table. If it is not on the cache, most likely is not going to be on the DB. There is one exception: item just added to the CS, e.g. new Element. The period between it is added to the DB and the changes are propagated to the cache will be inconsistent, but not dangerous. Just wait <cacheLifeTime> minutes. :param elementName: name of the element or list of element names :type elementName: str, list :param elementType: type of the element (StorageElement, ComputingElement, FTS, Catalog) :type elementType: str :param statusType: type of the status (meaningful only when elementType==StorageElement, otherwise it is 'all' or ['all']) :type statusType: str, list """ cacheMatch = self.rssCache.match(elementName, elementType, statusType) self.log.debug('__getRSSElementStatus') self.log.debug(cacheMatch) return cacheMatch def __getCSElementStatus(self, elementName, elementType, statusType, default): """ Gets from the CS the Element status :param elementName: name of the element :type elementName: str :param elementType: type of the element (StorageElement, ComputingElement, FTS, Catalog) :type elementType: str :param statusType: type of the status (meaningful only when elementType==StorageElement) :type statusType: str, list :param default: defult value :type default: None, str """ # DIRAC doesn't store the status of ComputingElements nor FTS in the CS, so here we can just return 'Active' if elementType in ('ComputingElement', 'FTS'): return S_OK({elementName: {'all': 'Active'}}) # If we are here it is because elementType is either 'StorageElement' or 'Catalog' if elementType == 'StorageElement': cs_path = "/Resources/StorageElements" elif elementType == 'Catalog': cs_path = "/Resources/FileCatalogs" statusType = ['Status'] if not isinstance(elementName, list): elementName = [elementName] if not isinstance(statusType, list): statusType = [statusType] result = {} for element in elementName: for sType in statusType: # Look in standard location, 'Active' by default res = gConfig.getValue("%s/%s/%s" % (cs_path, element, sType), 'Active') result.setdefault(element, {})[sType] = res if result: return S_OK(result) if default is not None: defList = [[el, statusType, default] for el in elementName] return S_OK(getDictFromList(defList)) _msg = "Element '%s', with statusType '%s' is unknown for CS." return S_ERROR(DErrno.ERESUNK, _msg % (elementName, statusType)) def __setRSSElementStatus(self, elementName, elementType, statusType, status, reason, tokenOwner): """ Sets on the RSS the Elements status """ expiration = datetime.utcnow() + timedelta(days=1) self.rssCache.acquireLock() try: res = self.rssClient.addOrModifyStatusElement('Resource', 'Status', name=elementName, elementType=elementType, status=status, statusType=statusType, reason=reason, tokenOwner=tokenOwner, tokenExpiration=expiration) if res['OK']: self.rssCache.refreshCache() if not res['OK']: _msg = 'Error updating Element (%s,%s,%s)' % (elementName, statusType, status) gLogger.warn('RSS: %s' % _msg) return res finally: # Release lock, no matter what. self.rssCache.releaseLock() def __setCSElementStatus(self, elementName, elementType, statusType, status): """ Sets on the CS the Elements status """ # DIRAC doesn't store the status of ComputingElements nor FTS in the CS, so here we can just do nothing if elementType in ('ComputingElement', 'FTS'): return S_OK() # If we are here it is because elementType is either 'StorageElement' or 'Catalog' statuses = self.rssConfig.getConfigStatusType(elementType) if statusType not in statuses: gLogger.error("%s is not a valid statusType" % statusType) return S_ERROR("%s is not a valid statusType: %s" % (statusType, statuses)) if elementType == 'StorageElement': cs_path = "/Resources/StorageElements" elif elementType == 'Catalog': cs_path = "/Resources/FileCatalogs" # FIXME: This a probably outdated location (new one is in /Operations/[]/Services/Catalogs) # but needs to be VO-aware statusType = 'Status' csAPI = CSAPI() csAPI.setOption("%s/%s/%s/%s" % (cs_path, elementName, elementType, statusType), status) res = csAPI.commitChanges() if not res['OK']: gLogger.warn('CS: %s' % res['Message']) return res def __getMode(self): """ Gets flag defined (or not) on the RSSConfiguration. If defined as 'Active', we use RSS, if not, we use the CS when possible (and WMS for Sites). """ res = self.rssConfig.getConfigState() if res == 'Active': if self.rssClient is None: self.rssClient = ResourceStatusClient() return True self.rssClient = None return False def isStorageElementAlwaysBanned(self, seName, statusType): """ Checks if the AlwaysBanned policy is applied to the SE given as parameter :param seName: string, name of the SE :param statusType: ReadAcces, WriteAccess, RemoveAccess, CheckAccess :returns: S_OK(True/False) """ res = getPoliciesThatApply({'name': seName, 'statusType': statusType}) if not res['OK']: self.log.error("isStorageElementAlwaysBanned: unable to get the information", res['Message']) return res isAlwaysBanned = 'AlwaysBanned' in [policy['type'] for policy in res['Value']] return S_OK(isAlwaysBanned)