def _getUserEmails(self): configResult = RssConfiguration.getnotificationGroups() if not configResult['OK']: return configResult try: notificationGroups = configResult['Value']['notificationGroups'] except KeyError: return S_ERROR('%s/notificationGroups not found') notifications = RssConfiguration.getNotifications() if not notifications['OK']: return notifications notifications = notifications['Value'] userEmails = [] for notificationGroupName in notificationGroups: try: userEmails.extend( notifications[notificationGroupName]['users']) except KeyError: self.log.error('%s not present' % notificationGroupName) return S_OK(userEmails)
def _getUserEmails(self): policyActions = RssConfiguration.getPolicyActions() if not policyActions['OK']: return policyActions try: notificationGroups = policyActions['Value'][ self.actionName]['notificationGroups'] except KeyError: return S_ERROR('%s/notificationGroups not found' % self.actionName) notifications = RssConfiguration.getNotifications() if not notifications['OK']: return notifications notifications = notifications['Value'] userEmails = [] for notificationGroupName in notificationGroups: try: userEmails.extend( notifications[notificationGroupName]['users']) except KeyError: gLogger.error('%s not present' % notificationGroupName) return S_OK(userEmails)
def _getUserEmails(self): configResult = RssConfiguration.getnotificationGroups() if not configResult["OK"]: return configResult try: notificationGroups = configResult["Value"]["notificationGroups"] except KeyError: return S_ERROR("%s/notificationGroups not found") notifications = RssConfiguration.getNotifications() if not notifications["OK"]: return notifications notifications = notifications["Value"] userEmails = [] for notificationGroupName in notificationGroups: try: userEmails.extend( notifications[notificationGroupName]["users"]) except KeyError: self.log.error("%s not present" % notificationGroupName) return S_OK(userEmails)
def _findPoliciesToCombine( self, singlePolicyRes ): """ method that iterates over the single policy results and checks the CS configuration of the policies looking for the option 'doNotCombine'. If it is present, that single policy result is discarded. :Parameters: **singlePolicyRes** - `list( dict )` list with every single policy result to be combined ( see _runPolicy for more details ) :return: `list( dict )` """ # Get policies configuration from the CS. We want to exclude the policies that # have set the option `doNotCombine` from this process. policiesConfiguration = RssConfiguration.getPolicies() if not policiesConfiguration['OK']: return policiesConfiguration policiesConfiguration = policiesConfiguration['Value'] # Function that let's us know if we should combine the result of a single policy # or not. def combinePolicy( policyResult ): # Extract policy name from the dictionary returned by PolicyCaller policyName = policyResult['Policy']['name'] try: # If doNotCombineResult is defined, the policy is not taken into account # to create the combined result. However, the single policy result remains _ = policiesConfiguration[ policyName ]['doNotCombineResult'] return False except KeyError: return True # Make a list of policies of which we want to merge their results return [ policyResult for policyResult in singlePolicyRes if combinePolicy( policyResult ) ]
def _sendMail(self, subject, body): userEmails = self._getUserEmails() if not userEmails['OK']: return userEmails # User email address used to send the emails from. fromAddress = RssConfiguration.RssConfiguration().getConfigFromAddress( ) for user in userEmails['Value']: #FIXME: should not I get the info from the RSS User cache ? resEmail = self.diracAdmin.sendMail(user, subject, body, fromAddress=fromAddress) if not resEmail['OK']: return S_ERROR('Cannot send email to user "%s"' % user) return S_OK() ################################################################################ #EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF
def _findPoliciesToCombine(self, singlePolicyRes): """ method that iterates over the single policy results and checks the CS configuration of the policies looking for the option 'doNotCombine'. If it is present, that single policy result is discarded. :Parameters: **singlePolicyRes** - `list( dict )` list with every single policy result to be combined ( see _runPolicy for more details ) :return: `list( dict )` """ # Get policies configuration from the CS. We want to exclude the policies that # have set the option `doNotCombine` from this process. policiesConfiguration = RssConfiguration.getPolicies() if not policiesConfiguration['OK']: return policiesConfiguration policiesConfiguration = policiesConfiguration['Value'] # Function that let's us know if we should combine the result of a single policy # or not. def combinePolicy(policyResult): # Extract policy name from the dictionary returned by PolicyCaller policyName = policyResult['Policy']['name'] try: # If doNotCombineResult is defined, the policy is not taken into account # to create the combined result. However, the single policy result remains _ = policiesConfiguration[policyName]['doNotCombineResult'] return False except KeyError: return True # Make a list of policies of which we want to merge their results return [policyResult for policyResult in singlePolicyRes if combinePolicy(policyResult)]
def __init__(self): ''' The client tries to connect to :class:ResourceStatusDB by default. If it fails, then tries to connect to the Service :class:ResourceStatusHandler. ''' self.rssService = RPCClient("ResourceStatus/ResourceStatus") self.validElements = RssConfiguration.getValidElements()
def execute( self ): # try: # Cleans history tables from entries older than 6 months. now = datetime.utcnow().replace( microsecond = 0, second = 0 ) sixMonthsAgo = now - timedelta( days = 180 ) validElements = RssConfiguration.getValidElements() for granularity in validElements: #deleter = getattr( self.rsClient, 'delete%sHistory' % g ) kwargs = { 'meta' : { 'minor' : { 'DateEnd' : sixMonthsAgo } } } self.log.info( 'Deleting %sHistory older than %s' % ( granularity, sixMonthsAgo ) ) res = self.rsClient.deleteElementHistory( granularity, **kwargs ) if not res[ 'OK' ]: self.log.error( res[ 'Message' ] ) # Cleans ClientsCache table from DownTimes older than a day. aDayAgo = now - timedelta( days = 1 ) kwargs = { 'meta' : { 'value' : 'EndDate', 'columns': 'Opt_ID', 'minor' : { 'Result' : str( aDayAgo ) } } } opt_IDs = self.rmClient.getClientCache( **kwargs ) opt_IDs = [ ID[ 0 ] for ID in opt_IDs[ 'Value' ] ] if opt_IDs: self.log.info( 'Found %s ClientCache items to be deleted' % len( opt_IDs) ) self.log.debug( opt_IDs ) res = self.rmClient.deleteClientCache( opt_ID = opt_IDs ) if not res[ 'OK' ]: self.log.error( res[ 'Message' ] ) # Cleans AccountingCache table from plots not updated nor checked in the last 30 mins anHourAgo = now - timedelta( minutes = 30 ) self.log.info( 'Deleting AccountingCache older than %s' % ( anHourAgo ) ) res = self.rmClient.deleteAccountingCache( meta = {'minor': { 'LastCheckTime' : anHourAgo }} ) if not res[ 'OK' ]: self.log.error( res[ 'Message' ] ) # Cleans PolicyResultLog twoWeeksAgo = now - timedelta( days = 10 ) self.log.info( 'Deleting PolicyResultLog older than %s' % ( twoWeeksAgo ) ) res = self.rmClient.deletePolicyResultLog( meta = {'minor': { 'LastCheckTime' : twoWeeksAgo }} ) if not res[ 'OK' ]: self.log.error( res[ 'Message' ] ) return S_OK()
def doCommand(self): """ Uses :meth:`DIRAC.ResourceStatusSystem.Client.ResourceStatusClient.getMonitoredStatus` :params: :attr:`args`: a tuple - `args[0]`: string - should be a ValidElement - `args[1]`: string - should be the name of the ValidElement - `args[2]`: optional string - a ValidElement (get status of THIS ValidElement for name in args[1], will call getGeneralName) :returns: {'MonitoredStatus': 'Active'|'Probing'|'Banned'} """ # try: validElements = RssConfiguration.getValidElements() if len(self.args) == 3: if validElements.index(self.args[2]) >= validElements.index( self.args[0]): return self.returnERROR( S_ERROR('Error in MonitoredStatus_Command')) toBeFound = self.rsClient.getGeneralName(self.args[0], self.args[1], self.args[2])['Value'] else: toBeFound = self.args[1] res = self.rsClient.getMonitoredStatus(self.args[2], toBeFound) if res['OK']: res = res['Value'] if res: res = S_OK(res[0][0]) else: res = S_OK(None) else: res = self.returnERROR(res) # except Exception, e: # _msg = '%s (%s): %s' % ( self.__class__.__name__, self.args, e ) # gLogger.exception( _msg ) # return S_ERROR( _msg ) return res # doCommand.__doc__ = Command.doCommand.__doc__ + doCommand.__doc__ ################################################################################ #EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF
def __init__(self, serviceIn=None): ''' The client tries to connect to :class:ResourceStatusDB by default. If it fails, then tries to connect to the Service :class:ResourceStatusHandler. ''' if not serviceIn: #self.gate = ResourceStatusDB() self.gate = RPCClient("ResourceStatus/ResourceStatus") else: self.gate = serviceIn self.validElements = RssConfiguration.getValidElements()
def __init__( self , serviceIn = None ): ''' The client tries to connect to :class:ResourceStatusDB by default. If it fails, then tries to connect to the Service :class:ResourceStatusHandler. ''' if not serviceIn: #self.gate = ResourceStatusDB() self.gate = RPCClient( "ResourceStatus/ResourceStatus" ) else: self.gate = serviceIn self.validElements = RssConfiguration.getValidElements()
def _getUserEmails( self ): policyActions = RssConfiguration.getPolicyActions() if not policyActions[ 'OK' ]: return policyActions try: notificationGroups = policyActions[ 'Value' ][ self.actionName ][ 'notificationGroups' ] except KeyError: return S_ERROR( '%s/notificationGroups not found' % self.actionName ) notifications = RssConfiguration.getNotifications() if not notifications[ 'OK' ]: return notifications notifications = notifications[ 'Value' ] userEmails = [] for notificationGroupName in notificationGroups: try: userEmails.extend( notifications[ notificationGroupName ][ 'users' ] ) except KeyError: gLogger.error( '%s not present' % notificationGroupName ) return S_OK( userEmails )
def _getUserEmails( self ): configResult = RssConfiguration.getnotificationGroups() if not configResult[ 'OK' ]: return configResult try: notificationGroups = configResult[ 'Value' ][ 'notificationGroups' ] except KeyError: return S_ERROR( '%s/notificationGroups not found' ) notifications = RssConfiguration.getNotifications() if not notifications[ 'OK' ]: return notifications notifications = notifications[ 'Value' ] userEmails = [] for notificationGroupName in notificationGroups: try: userEmails.extend( notifications[ notificationGroupName ][ 'users' ] ) except KeyError: self.log.error( '%s not present' % notificationGroupName ) return S_OK( userEmails )
def status_of_value( value ): ''' To be refactored ''' # Hack: rely on the order of values in ValidStatus validStatus = RssConfiguration.getValidStatus() try: return validStatus[ value ] except IndexError: #Temporary fix, not anymore InvalidStatus exception raising gLogger.error( 'status_of_value returning -1' ) return -1 ################################################################################ #EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF
def doCommand( self ): """ Uses :meth:`DIRAC.ResourceStatusSystem.Client.ResourceStatusClient.getMonitoredStatus` :params: :attr:`args`: a tuple - `args[0]`: string - should be a ValidElement - `args[1]`: string - should be the name of the ValidElement - `args[2]`: optional string - a ValidElement (get status of THIS ValidElement for name in args[1], will call getGeneralName) :returns: {'MonitoredStatus': 'Active'|'Probing'|'Banned'} """ # try: validElements = RssConfiguration.getValidElements() if len( self.args ) == 3: if validElements.index( self.args[2] ) >= validElements.index( self.args[0] ): return self.returnERROR( S_ERROR( 'Error in MonitoredStatus_Command' ) ) toBeFound = self.rsClient.getGeneralName( self.args[0], self.args[1], self.args[2] )[ 'Value' ] else: toBeFound = self.args[1] res = self.rsClient.getMonitoredStatus( self.args[2], toBeFound ) if res[ 'OK' ]: res = res[ 'Value' ] if res: res = S_OK( res[ 0 ][ 0 ] ) else: res = S_OK( None ) else: res = self.returnERROR( res ) # except Exception, e: # _msg = '%s (%s): %s' % ( self.__class__.__name__, self.args, e ) # gLogger.exception( _msg ) # return S_ERROR( _msg ) return res # doCommand.__doc__ = Command.doCommand.__doc__ + doCommand.__doc__ ################################################################################ #EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF
def setArgs(self, argsIn): ''' Set `self.args`. :params: :attr:`argsIn`: a tuple: (Module Command doesn't handle lists for now.) - `args[0]` should be a ValidElement - `args[1]` should be the name of the ValidElement ''' self.args = argsIn validElements = RssConfiguration.getValidElements() if self.args[0] not in validElements: gLogger.error('PolicyBase.setArgs got wrong ValidElement')
def setArgs( self, argsIn ): ''' Set `self.args`. :params: :attr:`argsIn`: a tuple: (Module Command doesn't handle lists for now.) - `args[0]` should be a ValidElement - `args[1]` should be the name of the ValidElement ''' self.args = argsIn validElements = RssConfiguration.getValidElements() if self.args[0] not in validElements: gLogger.error( 'PolicyBase.setArgs got wrong ValidElement' )
def _runPolicies(self, policies, decissionParams=None): if decissionParams is None: decissionParams = self.decissionParams validStatus = RssConfiguration.getValidStatus() if not validStatus['OK']: return validStatus validStatus = validStatus['Value'] policyInvocationResults = [] for policyDict in policies: policyInvocationResult = self.pCaller.policyInvocation( decissionParams, policyDict) if not policyInvocationResult['OK']: # We should never enter this line ! Just in case there are policies # missconfigured ! _msg = 'runPolicies no OK: %s' % policyInvocationResult gLogger.error(_msg) return S_ERROR(_msg) policyInvocationResult = policyInvocationResult['Value'] if not 'Status' in policyInvocationResult: _msg = 'runPolicies (no Status): %s' % policyInvocationResult gLogger.error(_msg) return S_ERROR(_msg) if not policyInvocationResult['Status'] in validStatus: _msg = 'runPolicies ( not valid status ) %s' % policyInvocationResult[ 'Status'] gLogger.error(_msg) return S_ERROR(_msg) if not 'Reason' in policyInvocationResult: _msg = 'runPolicies (no Reason): %s' % policyInvocationResult gLogger.error(_msg) return S_ERROR(_msg) policyInvocationResults.append(policyInvocationResult) return S_OK(policyInvocationResults)
def doCommand(self): """ Uses :meth:`DIRAC.ResourceStatusSystem.Client.ResourceStatusClient.getMonitoredStatus` :params: :attr:`args`: a tuple - `args[0]`: string - should be a ValidElement - `args[1]`: string - should be the name of the ValidElement - `args[2]`: optional string - a ValidElement (get status of THIS ValidElement for name in args[1], will call getGeneralName) :returns: {'MonitoredStatus': 'Active'|'Probing'|'Banned'} """ super(MonitoredStatus_Command, self).doCommand() self.APIs = initAPIs(self.__APIs__, self.APIs) try: validElements = RssConfiguration.getValidElements() if len(self.args) == 3: if validElements.index(self.args[2]) >= validElements.index(self.args[0]): return {"Result": S_ERROR("Error in MonitoredStatus_Command")} toBeFound = self.APIs["ResourceStatusClient"].getGeneralName(self.args[0], self.args[1], self.args[2])[ "Value" ] else: toBeFound = self.args[1] res = self.APIs["ResourceStatusClient"].getMonitoredStatus(self.args[2], toBeFound) if res["OK"]: res = res["Value"] if res: res = S_OK(res[0][0]) else: res = S_OK(None) except Exception, e: _msg = "%s (%s): %s" % (self.__class__.__name__, self.args, e) gLogger.exception(_msg) return {"Result": S_ERROR(_msg)}
def _runPolicies( self, policies, decissionParams = None ): if decissionParams is None: decissionParams = self.decissionParams validStatus = RssConfiguration.getValidStatus() if not validStatus[ 'OK' ]: return validStatus validStatus = validStatus[ 'Value' ] policyInvocationResults = [] for policyDict in policies: policyInvocationResult = self.pCaller.policyInvocation( decissionParams, policyDict ) if not policyInvocationResult[ 'OK' ]: # We should never enter this line ! Just in case there are policies # missconfigured ! _msg = 'runPolicies no OK: %s' % policyInvocationResult gLogger.error( _msg ) return S_ERROR( _msg ) policyInvocationResult = policyInvocationResult[ 'Value' ] if not 'Status' in policyInvocationResult: _msg = 'runPolicies (no Status): %s' % policyInvocationResult gLogger.error( _msg ) return S_ERROR( _msg ) if not policyInvocationResult[ 'Status' ] in validStatus: _msg = 'runPolicies ( not valid status ) %s' % policyInvocationResult[ 'Status' ] gLogger.error( _msg ) return S_ERROR( _msg ) if not 'Reason' in policyInvocationResult: _msg = 'runPolicies (no Reason): %s' % policyInvocationResult gLogger.error( _msg ) return S_ERROR( _msg ) policyInvocationResults.append( policyInvocationResult ) return S_OK( policyInvocationResults )
def initialize(self): # Attribute defined outside __init__ # pylint: disable-msg=W0201 try: self.rsClient = ResourceStatusClient() self.rmClient = ResourceManagementClient() validElements = RssConfiguration.getValidElements() self.historyTables = ['%sHistory' % x for x in validElements] return S_OK() except Exception: errorStr = "CacheCleanerAgent initialization" self.log.exception(errorStr) return S_ERROR(errorStr)
def __getPolTypes( self, granularity, statusType=None, status=None, formerStatus=None, newStatus=None, siteType=None, serviceType=None, resourceType=None ): """Get Policy Types from config that match the given keyword arguments. Always returns a generator object, possibly empty.""" # This dict is constructed to be used with function dictMatch that # helps selecting policies. **kwargs are not used due to the fact # that it's too dangerous here. argsdict = {'Granularity' : granularity, 'StatusType' : statusType, 'Status' : status, 'FormerStatus' : formerStatus, 'NewStatus' : newStatus, 'SiteType' : siteType, 'ServiceType' : serviceType, 'ResourceType' : resourceType } pTconfig = RssConfiguration.getValidPolicyTypes() return (pt for pt in pTconfig if Utils.dictMatch(argsdict, pTconfig[pt]))
def initialize( self ): # Attribute defined outside __init__ # pylint: disable-msg=W0201 try: self.rsClient = ResourceStatusClient() self.rmClient = ResourceManagementClient() validElements = RssConfiguration.getValidElements() self.historyTables = [ '%sHistory' % x for x in validElements ] return S_OK() except Exception: errorStr = "CacheCleanerAgent initialization" self.log.exception( errorStr ) return S_ERROR( errorStr )
def __getPolicyActionsThatApply( decisionParams ): ''' Method that matches the input dictionary with the policy actions configuration in the CS. It returns a list of policy actions names that matched. ''' policyActionsThatApply = [] # Get policies configuration metadata from CS. policyActionsConfig = RssConfiguration.getPolicyActions() if not policyActionsConfig[ 'OK' ]: return policyActionsConfig policyActionsConfig = policyActionsConfig[ 'Value' ] # Get policies that match the given decissionParameters for policyActionName, policyActionConfig in policyActionsConfig.items(): policyMatch = Utils.configMatch( decisionParams, policyActionConfig ) if policyMatch: policyActionsThatApply.append( policyActionName ) return S_OK( policyActionsThatApply )
gLogger.error('Status not found') Script.showHelp() DIRAC.exit(2) from DIRAC.Core.Security.ProxyInfo import getProxyInfo from DIRAC.ResourceStatusSystem import ValidStatus from DIRAC.ResourceStatusSystem.Client.ResourceStatusClient import ResourceStatusClient from DIRAC.ResourceStatusSystem.Utilities import RssConfiguration res = getProxyInfo() if not res['OK']: gLogger.error("Failed to get proxy information", res['Message']) DIRAC.exit(2) userName = res['Value']['username'] validElements = RssConfiguration.getValidElements() if not params['g'] in validElements: gLogger.error('"%s" is not a valid granularity' % params['g']) DIRAC.exit(2) if not params['a'] in ValidStatus: gLogger.error('"%s" is not a valid status' % params['a']) DIRAC.exit(2) if not params.has_key('t'): params['t'] = None if not params.has_key('r'): params['r'] = 'Status forced by %s' % userName rsCl = ResourceStatusClient()
def execute(self): ''' The main TokenAgent execution method. Checks for tokens owned by users that are expiring, and notifies those users. Calls rsClient.setToken() to set 'RS_SVC' as owner for those tokens that expired. ''' adminMail = '' try: reason = 'Out of date token' #reAssign the token to RS_SVC #for g in self.ELEMENTS: validElements = RssConfiguration.getValidElements() for granularity in validElements: tokensExpired = self.rsClient.getTokens( granularity, tokenExpiration=datetime.datetime.utcnow()) if tokensExpired['Value']: adminMail += '\nLIST OF EXPIRED %s TOKENS\n' % granularity adminMail += '%s|%s|%s\n' % ( 'user'.ljust(20), 'name'.ljust(15), 'status type') for token in tokensExpired['Value']: name = token[1] stype = token[2] user = token[9] self.rsClient.setToken( granularity, name, stype, reason, 'RS_SVC', datetime.datetime(9999, 12, 31, 23, 59, 59)) adminMail += ' %s %s %s\n' % (user.ljust(20), name.ljust(15), stype) #notify token owners inNHours = datetime.datetime.utcnow() + datetime.timedelta( hours=self.notifyHours) #for g in self.ELEMENTS: for granularity in validElements: tokensExpiring = self.rsClient.getTokens( granularity, tokenExpiration=inNHours) if tokensExpiring['Value']: adminMail += '\nLIST OF EXPIRING %s TOKENS\n' % granularity adminMail += '%s|%s|%s\n' % ( 'user'.ljust(20), 'name'.ljust(15), 'status type') for token in tokensExpiring['Value']: name = token[1] stype = token[2] user = token[9] adminMail += '\n %s %s %s\n' % (user.ljust(20), name.ljust(15), stype) #If user is RS_SVC, we ignore this, whenever the token is out, this #agent will set again the token to RS_SVC if user == 'RS_SVC': continue pdp = PDP(granularity=granularity, name=name, statusType=stype) decision = pdp.takeDecision() pcresult = decision['PolicyCombinedResult'] spresult = decision['SinglePolicyResults'] expiration = token[10] mailMessage = "The token for %s %s ( %s )" % (granularity, name, stype) mailMessage = mailMessage + " will expire on %s\n\n" % expiration mailMessage = mailMessage + "You can renew it with command 'dirac-rss-renew-token'.\n" mailMessage = mailMessage + "If you don't take any action, RSS will take control of the resource.\n\n" policyMessage = '' if pcresult['Action']: policyMessage += " Policies applied will set status to %s.\n" % pcresult[ 'Status'] for spr in spresult: policyMessage += " %s Status->%s\n" % ( spr['PolicyName'].ljust(25), spr['Status']) mailMessage += policyMessage adminMail += policyMessage self.noClient.sendMail( self.rmClient.getUserRegistryCache(user)['Value'][0] [2], 'Token for %s is expiring' % name, mailMessage) if adminMail != '': #FIXME: 'ubeda' is not generic ;p self.noClient.sendMail( self.rmClient.getUserRegistryCache('ubeda')['Value'][0][2], "Token's summary", adminMail) return S_OK() except Exception: errorStr = "TokenAgent execution" self.log.exception(errorStr) return S_ERROR(errorStr) ################################################################################ #EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF
def execute(self): # try: # Cleans history tables from entries older than 6 months. now = datetime.utcnow().replace(microsecond=0, second=0) sixMonthsAgo = now - timedelta(days=180) validElements = RssConfiguration.getValidElements() for granularity in validElements: #deleter = getattr( self.rsClient, 'delete%sHistory' % g ) kwargs = {'meta': {'minor': {'DateEnd': sixMonthsAgo}}} self.log.info('Deleting %sHistory older than %s' % (granularity, sixMonthsAgo)) res = self.rsClient.deleteElementHistory(granularity, **kwargs) if not res['OK']: self.log.error(res['Message']) # Cleans ClientsCache table from DownTimes older than a day. aDayAgo = now - timedelta(days=1) kwargs = { 'meta': { 'value': 'EndDate', 'columns': 'Opt_ID', 'minor': { 'Result': str(aDayAgo) } } } opt_IDs = self.rmClient.getClientCache(**kwargs) opt_IDs = [ID[0] for ID in opt_IDs['Value']] if opt_IDs: self.log.info('Found %s ClientCache items to be deleted' % len(opt_IDs)) self.log.debug(opt_IDs) res = self.rmClient.deleteClientCache(opt_ID=opt_IDs) if not res['OK']: self.log.error(res['Message']) # Cleans AccountingCache table from plots not updated nor checked in the last 30 mins anHourAgo = now - timedelta(minutes=30) self.log.info('Deleting AccountingCache older than %s' % (anHourAgo)) res = self.rmClient.deleteAccountingCache( meta={'minor': { 'LastCheckTime': anHourAgo }}) if not res['OK']: self.log.error(res['Message']) # Cleans PolicyResultLog twoWeeksAgo = now - timedelta(days=10) self.log.info('Deleting PolicyResultLog older than %s' % (twoWeeksAgo)) res = self.rmClient.deletePolicyResultLog( meta={'minor': { 'LastCheckTime': twoWeeksAgo }}) if not res['OK']: self.log.error(res['Message']) return S_OK()
def __getPolicyActionsThatApply2(decissionParams, singlePolicyResults, policyCombinedResults): ''' Method that matches the input dictionary with the policy actions configuration in the CS. It returns a list of policy actions names that matched. ''' policyActionsThatApply = [] # Get policies configuration metadata from CS. policyActionsConfig = RssConfiguration.getPolicyActions() if not policyActionsConfig['OK']: return policyActionsConfig policyActionsConfig = policyActionsConfig['Value'] # Let's create a dictionary to use it with configMatch policyResults = {} for policyResult in singlePolicyResults: try: policyResults[policyResult['Policy'] ['name']] = policyResult['Status'] except KeyError: continue # Get policies that match the given decissionParameters for policyActionName, policyActionConfig in policyActionsConfig.items( ): # The parameter policyType is mandatory. If not present, we pick policyActionName try: policyActionType = policyActionConfig['actionType'][0] except KeyError: policyActionType = policyActionName #continue # We get matchParams to be compared against decissionParams policyActionMatchParams = policyActionConfig.get('matchParams', {}) policyMatch = Utils.configMatch(decissionParams, policyActionMatchParams) #policyMatch = Utils.configMatch( decissionParams, policyActionConfig ) if not policyMatch: continue # Let's check single policy results # Assumed structure: # ... # policyResults # <PolicyName> = <PolicyResult1>,<PolicyResult2>... policyActionPolicyResults = policyActionConfig.get( 'policyResults', {}) policyResultsMatch = Utils.configMatch(policyResults, policyActionPolicyResults) if not policyResultsMatch: continue # combinedResult # \Status = X,Y # \Reason = asdasd,asdsa policyActionCombinedResult = policyActionConfig.get( 'combinedResult', {}) policyCombinedMatch = Utils.configMatch( policyCombinedResults, policyActionCombinedResult) if not policyCombinedMatch: continue #policyActionsThatApply.append( policyActionName ) # They may not be necessarily the same policyActionsThatApply.append((policyActionName, policyActionType)) return S_OK(policyActionsThatApply)
def initSEs(): """ Initializes SEs statuses taking their values from the CS. """ from DIRAC import gConfig from DIRAC.DataManagementSystem.Utilities.DMSHelpers import DMSHelpers from DIRAC.ResourceStatusSystem.Utilities import CSHelpers, RssConfiguration from DIRAC.ResourceStatusSystem.PolicySystem import StateMachine from DIRAC.ResourceStatusSystem.Client import ResourceStatusClient # WarmUp local copy CSHelpers.warmUp() subLogger.info("Initializing SEs") rssClient = ResourceStatusClient.ResourceStatusClient() statuses = StateMachine.RSSMachine(None).getStates() statusTypes = RssConfiguration.RssConfiguration().getConfigStatusType( "StorageElement") reason = "dirac-rss-sync" subLogger.debug(statuses) subLogger.debug(statusTypes) for se in DMSHelpers().getStorageElements(): subLogger.debug(se) opts = gConfig.getOptionsDict("/Resources/StorageElements/%s" % se) if not opts["OK"]: subLogger.warn(opts["Message"]) continue opts = opts["Value"] subLogger.debug(opts) # We copy the list into a new object to remove items INSIDE the loop ! statusTypesList = statusTypes[:] for statusType, status in opts.items(): # Sanity check... if statusType not in statusTypesList: continue # Transforms statuses to RSS terms if status in ("NotAllowed", "InActive"): status = "Banned" if status not in statuses: subLogger.error("%s not a valid status for %s - %s" % (status, se, statusType)) continue # We remove from the backtracking statusTypesList.remove(statusType) subLogger.debug([se, statusType, status, reason]) result = rssClient.addOrModifyStatusElement( "Resource", "Status", name=se, statusType=statusType, status=status, elementType="StorageElement", tokenOwner="rs_svc", reason=reason, ) if not result["OK"]: subLogger.error("Failed to modify") subLogger.error(result["Message"]) continue # Backtracking: statusTypes not present on CS for statusType in statusTypesList: result = rssClient.addOrModifyStatusElement( "Resource", "Status", name=se, statusType=statusType, status=DEFAULT_STATUS, elementType="StorageElement", tokenOwner="rs_svc", reason=reason, ) if not result["OK"]: subLogger.error("Error in backtracking for %s,%s,%s" % (se, statusType, status)) subLogger.error(result["Message"]) return S_OK()
def enforce( self, granularity = None, name = None, statusType = None, status = None, formerStatus = None, reason = None, siteType = None, serviceType = None, resourceType = None, tokenOwner = None, useNewRes = False, knownInfo = None ): ''' Enforce policies for given set of keyworkds. To be better explained. ''' ## real ban flag ######################################################### realBan = False if tokenOwner is not None: if tokenOwner == 'RS_SVC': realBan = True ## sanitize input ########################################################## ## IS IT REALLY NEEDED ?? validElements = RssConfiguration.getValidElements() if granularity is not None and granularity not in validElements: return S_ERROR( 'Granularity "%s" not valid' % granularity ) validStatusTypes = RssConfiguration.getValidStatusTypes() if statusType is not None and statusType not in validStatusTypes[ granularity ]['StatusType']: return S_ERROR( 'StatusType "%s" not valid' % statusType ) validStatus = RssConfiguration.getValidStatus() if status is not None and status not in validStatus: return S_ERROR( 'Status "%s" not valid' % status ) validStatus = RssConfiguration.getValidStatus() if formerStatus is not None and formerStatus not in validStatus: return S_ERROR( 'FormerStatus "%s" not valid' % formerStatus ) validSiteTypes = RssConfiguration.getValidSiteTypes() if siteType is not None and siteType not in validSiteTypes: return S_ERROR( 'SiteType "%s" not valid' % siteType ) validServiceTypes = RssConfiguration.getValidServiceTypes() if serviceType is not None and serviceType not in validServiceTypes: return S_ERROR( 'ServiceType "%s" not valid' % serviceType ) validResourceTypes = RssConfiguration.getValidResourceTypes() if resourceType is not None and resourceType not in validResourceTypes: return S_ERROR( 'ResourceType "%s" not valid' % resourceType ) ## policy setup ############################################################ self.pdp.setup( granularity = granularity, name = name, statusType = statusType, status = status, formerStatus = formerStatus, reason = reason, siteType = siteType, serviceType = serviceType, resourceType = resourceType, useNewRes = useNewRes ) ## policy decision ######################################################### resDecisions = self.pdp.takeDecision( knownInfo = knownInfo ) ## record all results before doing anything else for resP in resDecisions[ 'SinglePolicyResults' ]: if not resP.has_key( 'OLD' ): self.clients[ "rmClient" ].insertPolicyResultLog( granularity, name, resP[ 'PolicyName' ], statusType, resP[ 'Status' ], resP[ 'Reason' ], now ) else: gLogger.warn( 'OLD: %s' % resP ) res = resDecisions[ 'PolicyCombinedResult' ] actionBaseMod = "DIRAC.ResourceStatusSystem.PolicySystem.Actions" # Security mechanism in case there is no PolicyType returned if res == {}: EmptyAction(granularity, name, statusType, resDecisions).run() else: policyType = res[ 'PolicyType' ] if 'Resource_PolType' in policyType: action = Utils.voimport( '%s.ResourceAction' % actionBaseMod ) action.ResourceAction(granularity, name, statusType, resDecisions, rsClient=self.rsClient, rmClient=self.rmClient).run() if 'Alarm_PolType' in policyType: action = Utils.voimport( '%s.AlarmAction' % actionBaseMod ) action.AlarmAction(granularity, name, statusType, resDecisions, Clients=self.clients, Params={"Granularity" : granularity, "SiteType" : siteType, "ServiceType" : serviceType, "ResourceType" : resourceType}).run() if 'RealBan_PolType' in policyType and realBan: action = Utils.voimport( '%s.RealBanAction' % actionBaseMod ) action.RealBanAction(granularity, name, resDecisions).run() return resDecisions ################################################################################ #EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF
def __getPoliciesThatApply(self, decissionParams): ''' Method that matches the input dictionary with the policies configuration in the CS. It returns a list of policy dictionaries that matched. ''' policiesThatApply = [] # Get policies configuration metadata from CS. policiesConfig = RssConfiguration.getPolicies() if not policiesConfig['OK']: return policiesConfig policiesConfig = policiesConfig['Value'] # Each policy, has the following format # <policyName> # \ # policyType = <policyType> # matchParams # \ # ... # configParams # \ # ... # Get policies that match the given decissionParameters for policyName, policySetup in policiesConfig.items(): # The parameter policyType replaces policyName, so if it is not present, # we pick policyName try: policyType = policySetup['policyType'][0] except KeyError: policyType = policyName #continue # The section matchParams is not mandatory, so we set {} as default. policyMatchParams = policySetup.get('matchParams', {}) # FIXME: make sure the values in the policyConfigParams dictionary are typed !! policyConfigParams = {} #policyConfigParams = policySetup.get( 'configParams', {} ) policyMatch = Utils.configMatch(decissionParams, policyMatchParams) if policyMatch: policiesThatApply.append( (policyName, policyType, policyConfigParams)) policiesToBeLoaded = [] # Gets policies parameters from code. for policyName, policyType, _policyConfigParams in policiesThatApply: try: policyMeta = self.policies[policyType] except KeyError: continue # We are not going to use name / type anymore, but we keep them for debugging # and future usage. policyDict = {'name': policyName, 'type': policyType, 'args': {}} # args is one of the parameters we are going to use on the policies. We copy # the defaults and then we update if with whatever comes from the CS. policyDict.update(policyMeta) # FIXME: watch out, args can be None ! #policyDict[ 'args' ].update( policyConfigParams ) policiesToBeLoaded.append(policyDict) return S_OK(policiesToBeLoaded)
def enforce(self, granularity=None, name=None, statusType=None, status=None, formerStatus=None, reason=None, siteType=None, serviceType=None, resourceType=None, tokenOwner=None, useNewRes=False, knownInfo=None): ''' Enforce policies for given set of keyworkds. To be better explained. ''' ## real ban flag ######################################################### realBan = False if tokenOwner is not None: if tokenOwner == 'RS_SVC': realBan = True ## sanitize input ########################################################## ## IS IT REALLY NEEDED ?? validElements = RssConfiguration.getValidElements() if granularity is not None and granularity not in validElements: return S_ERROR('Granularity "%s" not valid' % granularity) validStatusTypes = RssConfiguration.getValidStatusTypes() if statusType is not None and statusType not in validStatusTypes[ granularity]['StatusType']: return S_ERROR('StatusType "%s" not valid' % statusType) validStatus = RssConfiguration.getValidStatus() if status is not None and status not in validStatus: return S_ERROR('Status "%s" not valid' % status) validStatus = RssConfiguration.getValidStatus() if formerStatus is not None and formerStatus not in validStatus: return S_ERROR('FormerStatus "%s" not valid' % formerStatus) validSiteTypes = RssConfiguration.getValidSiteTypes() if siteType is not None and siteType not in validSiteTypes: return S_ERROR('SiteType "%s" not valid' % siteType) validServiceTypes = RssConfiguration.getValidServiceTypes() if serviceType is not None and serviceType not in validServiceTypes: return S_ERROR('ServiceType "%s" not valid' % serviceType) validResourceTypes = RssConfiguration.getValidResourceTypes() if resourceType is not None and resourceType not in validResourceTypes: return S_ERROR('ResourceType "%s" not valid' % resourceType) ## policy setup ############################################################ self.pdp.setup(granularity=granularity, name=name, statusType=statusType, status=status, formerStatus=formerStatus, reason=reason, siteType=siteType, serviceType=serviceType, resourceType=resourceType, useNewRes=useNewRes) ## policy decision ######################################################### resDecisions = self.pdp.takeDecision(knownInfo=knownInfo) ## record all results before doing anything else for resP in resDecisions['SinglePolicyResults']: if not resP.has_key('OLD'): self.clients["rmClient"].insertPolicyResultLog( granularity, name, resP['PolicyName'], statusType, resP['Status'], resP['Reason'], now) else: gLogger.warn('OLD: %s' % resP) res = resDecisions['PolicyCombinedResult'] actionBaseMod = "DIRAC.ResourceStatusSystem.PolicySystem.Actions" # Security mechanism in case there is no PolicyType returned if res == {}: EmptyAction(granularity, name, statusType, resDecisions).run() else: policyType = res['PolicyType'] if 'Resource_PolType' in policyType: action = Utils.voimport('%s.ResourceAction' % actionBaseMod) action.ResourceAction(granularity, name, statusType, resDecisions, rsClient=self.rsClient, rmClient=self.rmClient).run() if 'Alarm_PolType' in policyType: action = Utils.voimport('%s.AlarmAction' % actionBaseMod) action.AlarmAction(granularity, name, statusType, resDecisions, Clients=self.clients, Params={ "Granularity": granularity, "SiteType": siteType, "ServiceType": serviceType, "ResourceType": resourceType }).run() if 'RealBan_PolType' in policyType and realBan: action = Utils.voimport('%s.RealBanAction' % actionBaseMod) action.RealBanAction(granularity, name, resDecisions).run() return resDecisions ################################################################################ #EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF
from DIRAC.Core.Security.ProxyInfo import getProxyInfo from DIRAC.ResourceStatusSystem.Client.ResourceStatusClient import ResourceStatusClient from DIRAC.ResourceStatusSystem.Client.ResourceManagementClient import ResourceManagementClient from DIRAC.ResourceStatusSystem.Utilities import RssConfiguration res = getProxyInfo() if not res['OK']: gLogger.error( "Failed to get proxy information", res['Message'] ) DIRAC.exit( 2 ) userName = res['Value']['username'] if not params.has_key( 'k' ): params[ 'k' ] = userName validElements = RssConfiguration.getValidElements() if not params[ 'g' ] in validElements: gLogger.error( '"%s" is not a valid granularity' % params[ 'g' ] ) DIRAC.exit( 2 ) if params[ 'k' ] != 'RS_SVC': rmc = ResourceManagementClient() u = rmc.getUserRegistryCache( login = params[ 'k' ] ) if not u[ 'OK' ] or not u[ 'Value' ]: gLogger.error( '"%s" is not a known user' % params[ 'k' ] ) DIRAC.exit( 2 ) if not params.has_key( 't' ): params[ 't' ] = None
def execute( self ): ''' The main TokenAgent execution method. Checks for tokens owned by users that are expiring, and notifies those users. Calls rsClient.setToken() to set 'RS_SVC' as owner for those tokens that expired. ''' adminMail = '' try: reason = 'Out of date token' #reAssign the token to RS_SVC #for g in self.ELEMENTS: validElements = RssConfiguration.getValidElements() for granularity in validElements: tokensExpired = self.rsClient.getTokens( granularity, tokenExpiration = datetime.datetime.utcnow() ) if tokensExpired[ 'Value' ]: adminMail += '\nLIST OF EXPIRED %s TOKENS\n' % granularity adminMail += '%s|%s|%s\n' % ( 'user'.ljust(20), 'name'.ljust(15), 'status type') for token in tokensExpired[ 'Value' ]: name = token[ 1 ] stype = token[ 2 ] user = token[ 9 ] self.rsClient.setToken( granularity, name, stype, reason, 'RS_SVC', datetime.datetime( 9999, 12, 31, 23, 59, 59 ) ) adminMail += ' %s %s %s\n' %( user.ljust(20), name.ljust(15), stype ) #notify token owners inNHours = datetime.datetime.utcnow() + datetime.timedelta( hours = self.notifyHours ) #for g in self.ELEMENTS: for granularity in validElements: tokensExpiring = self.rsClient.getTokens( granularity, tokenExpiration = inNHours ) if tokensExpiring[ 'Value' ]: adminMail += '\nLIST OF EXPIRING %s TOKENS\n' % granularity adminMail += '%s|%s|%s\n' % ( 'user'.ljust(20),'name'.ljust(15),'status type') for token in tokensExpiring[ 'Value' ]: name = token[ 1 ] stype = token[ 2 ] user = token[ 9 ] adminMail += '\n %s %s %s\n' %( user.ljust(20), name.ljust(15), stype ) #If user is RS_SVC, we ignore this, whenever the token is out, this #agent will set again the token to RS_SVC if user == 'RS_SVC': continue pdp = PDP( granularity = granularity, name = name, statusType = stype ) decision = pdp.takeDecision() pcresult = decision[ 'PolicyCombinedResult' ] spresult = decision[ 'SinglePolicyResults' ] expiration = token[ 10 ] mailMessage = "The token for %s %s ( %s )" % ( granularity, name, stype ) mailMessage = mailMessage + " will expire on %s\n\n" % expiration mailMessage = mailMessage + "You can renew it with command 'dirac-rss-renew-token'.\n" mailMessage = mailMessage + "If you don't take any action, RSS will take control of the resource.\n\n" policyMessage = '' if pcresult[ 'Action' ]: policyMessage += " Policies applied will set status to %s.\n" % pcresult[ 'Status' ] for spr in spresult: policyMessage += " %s Status->%s\n" % ( spr[ 'PolicyName' ].ljust(25), spr[ 'Status' ] ) mailMessage += policyMessage adminMail += policyMessage self.noClient.sendMail( self.rmClient.getUserRegistryCache( user )[ 'Value' ][ 0 ][ 2 ], 'Token for %s is expiring' % name, mailMessage ) if adminMail != '': #FIXME: 'ubeda' is not generic ;p self.noClient.sendMail( self.rmClient.getUserRegistryCache( 'ubeda' )[ 'Value' ][ 0 ][ 2 ], "Token's summary", adminMail ) return S_OK() except Exception: errorStr = "TokenAgent execution" self.log.exception( errorStr ) return S_ERROR( errorStr ) ################################################################################ #EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF#EOF
def initSEs(): ''' Initializes SEs statuses taking their values from the CS. ''' # WarmUp local copy CSHelpers.warmUp() subLogger.info('Initializing SEs') rssClient = ResourceStatusClient.ResourceStatusClient() statuses = StateMachine.RSSMachine(None).getStates() statusTypes = RssConfiguration.RssConfiguration().getConfigStatusType( 'StorageElement') reason = 'dirac-rss-sync' subLogger.debug(statuses) subLogger.debug(statusTypes) for se in DMSHelpers().getStorageElements(): subLogger.debug(se) opts = gConfig.getOptionsDict('/Resources/StorageElements/%s' % se) if not opts['OK']: subLogger.warn(opts['Message']) continue opts = opts['Value'] subLogger.debug(opts) # We copy the list into a new object to remove items INSIDE the loop ! statusTypesList = statusTypes[:] for statusType, status in opts.iteritems(): # Sanity check... if statusType not in statusTypesList: continue # Transforms statuses to RSS terms if status in ('NotAllowed', 'InActive'): status = 'Banned' if status not in statuses: subLogger.error('%s not a valid status for %s - %s' % (status, se, statusType)) continue # We remove from the backtracking statusTypesList.remove(statusType) subLogger.debug([se, statusType, status, reason]) result = rssClient.addOrModifyStatusElement( 'Resource', 'Status', name=se, statusType=statusType, status=status, elementType='StorageElement', tokenOwner='rs_svc', reason=reason) if not result['OK']: subLogger.error('Failed to modify') subLogger.error(result['Message']) continue # Backtracking: statusTypes not present on CS for statusType in statusTypesList: result = rssClient.addOrModifyStatusElement( 'Resource', 'Status', name=se, statusType=statusType, status=DEFAULT_STATUS, elementType='StorageElement', tokenOwner='rs_svc', reason=reason) if not result['OK']: subLogger.error('Error in backtracking for %s,%s,%s' % (se, statusType, status)) subLogger.error(result['Message']) return S_OK()
def __getPolicyActionsThatApply2( decisionParams, singlePolicyResults, policyCombinedResults ): ''' Method that matches the input dictionary with the policy actions configuration in the CS. It returns a list of policy actions names that matched. ''' policyActionsThatApply = [] # Get policies configuration metadata from CS. policyActionsConfig = RssConfiguration.getPolicyActions() if not policyActionsConfig[ 'OK' ]: return policyActionsConfig policyActionsConfig = policyActionsConfig[ 'Value' ] # Let's create a dictionary to use it with configMatch policyResults = {} for policyResult in singlePolicyResults: try: policyResults[ policyResult[ 'Policy' ][ 'name' ] ] = policyResult[ 'Status' ] except KeyError: continue # Get policies that match the given decissionParameters for policyActionName, policyActionConfig in policyActionsConfig.items(): # The parameter policyType is mandatory. If not present, we pick policyActionName try: policyActionType = policyActionConfig[ 'actionType' ][ 0 ] except KeyError: policyActionType = policyActionName #continue # We get matchParams to be compared against decisionParams policyActionMatchParams = policyActionConfig.get( 'matchParams', {} ) policyMatch = Utils.configMatch( decisionParams, policyActionMatchParams ) # policyMatch = Utils.configMatch( decisionParams, policyActionConfig ) if not policyMatch: continue # Let's check single policy results # Assumed structure: # ... # policyResults # <PolicyName> = <PolicyResult1>,<PolicyResult2>... policyActionPolicyResults = policyActionConfig.get( 'policyResults', {} ) policyResultsMatch = Utils.configMatch( policyResults, policyActionPolicyResults ) if not policyResultsMatch: continue # combinedResult # \Status = X,Y # \Reason = asdasd,asdsa policyActionCombinedResult = policyActionConfig.get( 'combinedResult', {} ) policyCombinedMatch = Utils.configMatch( policyCombinedResults, policyActionCombinedResult ) if not policyCombinedMatch: continue #policyActionsThatApply.append( policyActionName ) # They may not be necessarily the same policyActionsThatApply.append( ( policyActionName, policyActionType ) ) return S_OK( policyActionsThatApply )
def __getPoliciesThatApply( self, decisionParams ): ''' Method that matches the input dictionary with the policies configuration in the CS. It returns a list of policy dictionaries that matched. ''' policiesThatApply = [] # Get policies configuration metadata from CS. policiesConfig = RssConfiguration.getPolicies() if not policiesConfig[ 'OK' ]: return policiesConfig policiesConfig = policiesConfig[ 'Value' ] # Each policy, has the following format # <policyName> # \ # policyType = <policyType> # matchParams # \ # ... # configParams # \ # ... # Get policies that match the given decissionParameters for policyName, policySetup in policiesConfig.items(): # The parameter policyType replaces policyName, so if it is not present, # we pick policyName try: policyType = policySetup[ 'policyType' ][ 0 ] except KeyError: policyType = policyName #continue # The section matchParams is not mandatory, so we set {} as default. policyMatchParams = policySetup.get( 'matchParams', {} ) # FIXME: make sure the values in the policyConfigParams dictionary are typed !! policyConfigParams = {} #policyConfigParams = policySetup.get( 'configParams', {} ) policyMatch = Utils.configMatch( decisionParams, policyMatchParams ) if policyMatch: policiesThatApply.append( ( policyName, policyType, policyConfigParams ) ) policiesToBeLoaded = [] # Gets policies parameters from code. for policyName, policyType, _policyConfigParams in policiesThatApply: try: policyMeta = self.policies[ policyType ] except KeyError: continue # We are not going to use name / type anymore, but we keep them for debugging # and future usage. policyDict = { 'name' : policyName, 'type' : policyType, 'args' : {} } # args is one of the parameters we are going to use on the policies. We copy # the defaults and then we update if with whatever comes from the CS. policyDict.update( policyMeta ) # FIXME: watch out, args can be None ! #policyDict[ 'args' ].update( policyConfigParams ) policiesToBeLoaded.append( policyDict ) return S_OK( policiesToBeLoaded )
def getPolicyActionsThatApply( self, decisionParams, singlePolicyResults, policyCombinedResults ): """ Method that returns the actions to be triggered based on the original decision parameters ( decisionParams ), which also can apply to the method `getPoliciesThatApply`, each one of the policy results ( singlePolicyResults ) and the combined policy results ( policyCombinedResults ) as computed on the `PDP`. examples: >>> iGetter.getPolicyActionsThatApply( { 'name' : 'SiteA' },[],{} )[ 'Value' ] [ ( 'BanSiteA', 'BanSite' ) ] >>> iGetter.getPolicyActionsThatApply( { 'name' : 'SiteA' },[], { 'Status' : 'Active', 'Reason' : 'Blah' } )[ 'Value' ] [ ( 'BanSiteA', 'BanSite' ), ( 'EmailActive2Banned', 'EmailAction' ) ] :Parameters: **decisionParams** - `dict` dictionary with the parameters to match policies ( and actions in this case ) **singlePolicyResults** - `list( dict )` list containing the dictionaries returned by the policies evaluated **policyCombinedResults** - `dict` dictionary containing the combined result of the policies evaluation :return: S_OK( list ) / S_ERROR """ policyActionsThatApply = [] # Get policies configuration metadata from CS. policyActionsConfig = RssConfiguration.getPolicyActions() if not policyActionsConfig[ 'OK' ]: return policyActionsConfig policyActionsConfig = policyActionsConfig[ 'Value' ] # Let's create a dictionary to use it with configMatch policyResults = self._getPolicyResults( singlePolicyResults ) # Get policies that match the given decissionParameters for policyActionName, policyActionConfig in policyActionsConfig.iteritems(): # The parameter policyType is mandatory. If not present, we pick policyActionName try: policyActionType = policyActionConfig[ 'actionType' ][ 0 ] except KeyError: policyActionType = policyActionName # We get matchParams to be compared against decissionParams policyActionMatchParams = policyActionConfig.get( 'matchParams', {} ) if not Utils.configMatch( decisionParams, policyActionMatchParams ): continue # Let's check single policy results # Assumed structure: # ... # policyResults # <PolicyName> = <PolicyResult1>,<PolicyResult2>... policyActionPolicyResults = policyActionConfig.get( 'policyResults', {} ) if not Utils.configMatch( policyResults, policyActionPolicyResults ): continue # combinedResult # \Status = X,Y # \Reason = asdasd,asdsa policyActionCombinedResult = policyActionConfig.get( 'combinedResult', {} ) if not Utils.configMatch( policyCombinedResults, policyActionCombinedResult ): continue # They may not be necessarily the same policyActionsThatApply.append( ( policyActionName, policyActionType ) ) return S_OK( policyActionsThatApply )
def getPoliciesThatApply( self, decisionParams ): """ Given a dictionary, it matches it against all the policies configuration dictionaries as they are on the CS. Returns the policy dictionaries that produced a positive match plus their configuration in <self.policies>. examples: >>> # This matches all policies ! >>> iGetter.getPoliciesThatApply( {} ) [ { 'name' : 'AlwaysActiveForResource', 'type' : 'AlwaysActive', 'module' : 'AlwaysActivePolicy', 'description' : 'This is the AlwaysActive policy' 'command' : None, 'args' : {} },... ] >>> # There is no policy that matches BlahSite >>> iGetter.getPoliciesThatApply( { 'name' : 'BlahSite' } ) [] :Parameters: **decisionParams** - `dict` dictionary with the parameters to match policies. :return: S_OK() / S_ERROR """ policiesToBeLoaded = [] # Get policies configuration metadata from CS. policiesConfig = RssConfiguration.getPolicies() if not policiesConfig[ 'OK' ]: return policiesConfig policiesConfig = policiesConfig[ 'Value' ] # Get policies that match the given decissionParameters for policyName, policySetup in policiesConfig.iteritems(): # The section matchParams is not mandatory, so we set {} as default. policyMatchParams = policySetup.get( 'matchParams', {} ) if not Utils.configMatch( decisionParams, policyMatchParams ): continue # the policyName replaces the policyTipe if not present. This allows us to # define several policies of the same type on the CS. We just need to # give them different names and assign them the same policyType. try: policyType = policySetup[ 'policyType' ][ 0 ] except KeyError: policyType = policyName policyDict = { 'name' : policyName, 'type' : policyType, 'args' : {} } # Get policy static configuration try: policyDict.update( self.policies[ policyType ] ) except KeyError: continue policiesToBeLoaded.append( policyDict ) return S_OK( policiesToBeLoaded )
def getPoliciesThatApply( decisionParams ): """ Method that sanitizes the input parameters and returns the policies that match them. Matches the input dictionary with the policies configuration in the CS. It returns a list of policy dictionaries that matched. """ decisionParams = _sanitizedecisionParams( decisionParams ) gLogger.debug("Sanitized decisionParams: %s" % str(decisionParams)) policiesThatApply = [] # Get policies configuration metadata from CS. policiesConfig = RssConfiguration.getPolicies() if not policiesConfig[ 'OK' ]: return policiesConfig policiesConfig = policiesConfig[ 'Value' ] gLogger.debug("All policies: %s" %str(policiesConfig)) # Each policy, has the following format # <policyName> # \ # policyType = <policyType> # matchParams # \ # ... # configParams # \ # ... # Get policies that match the given decisionParameters for policyName, policySetup in policiesConfig.items(): # The parameter policyType replaces policyName, so if it is not present, # we pick policyName try: policyType = policySetup[ 'policyType' ][ 0 ] except KeyError: policyType = policyName #continue # The section matchParams is not mandatory, so we set {} as default. policyMatchParams = policySetup.get( 'matchParams', {} ) gLogger.debug("matchParams of %s: %s" %(policyName, str(policyMatchParams))) # FIXME: make sure the values in the policyConfigParams dictionary are typed !! policyConfigParams = {} #policyConfigParams = policySetup.get( 'configParams', {} ) policyMatch = Utils.configMatch( decisionParams, policyMatchParams ) gLogger.debug("PolicyMatch for decisionParams %s: %s" %(decisionParams, str(policyMatch))) policyFilter = _filterPolicies( decisionParams, policyMatchParams ) #WARNING: we need an additional filtering function when the matching #is not straightforward (e.g. when the policy specify a 'domain', while #the decisionParams has only the name of the element) if policyMatch and policyFilter: policiesThatApply.append( ( policyName, policyType, policyConfigParams ) ) gLogger.debug("policies that apply: %s" %str(policiesThatApply)) policiesToBeLoaded = [] # Gets policies parameters from code. for policyName, policyType, _policyConfigParams in policiesThatApply: try: configModule = Utils.voimport( 'DIRAC.ResourceStatusSystem.Policy.Configurations' ) policies = copy.deepcopy( configModule.POLICIESMETA ) policyMeta = policies[ policyType ] except KeyError: continue # We are not going to use name / type anymore, but we keep them for debugging # and future usage. policyDict = { 'name' : policyName, 'type' : policyType, 'args' : {} } # args is one of the parameters we are going to use on the policies. We copy # the defaults and then we update if with whatever comes from the CS. policyDict.update( policyMeta ) policiesToBeLoaded.append( policyDict ) return S_OK( policiesToBeLoaded )