def units_applicable(self, criteria, units): """ Detemine and report which of the specified content units is applicable to consumers specified by the I{criteria}. @param criteria: The consumer selection criteria. @type criteria: list @param units: A list of content units to be installed. @type units: list of: { type_id:<str>, unit_key:<dict> } @return: A dict: {consumer_id:[<ApplicabilityReport>]} @rtype: list """ result = {} conduit = ProfilerConduit() manager = managers.consumer_query_manager() ids = [c['id'] for c in manager.find_by_criteria(criteria)] manager = managers.consumer_profile_manager() profiles = manager.find_profiles(ids) for id in ids: for unit in units: typeid = unit['type_id'] profiler, cfg = self.__profiler(typeid) pc = self.__profiled_consumer(id) report = profiler.unit_applicable(pc, unit, cfg, conduit) report.unit = unit ulist = result.setdefault(id, []) ulist.append(report) return result
def post(self, request, consumer_id): """ Creates an async task to regenerate content applicability data for given consumer. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :param consumer_id: The consumer ID. :type consumer_id: str :raises MissingResource: if some parameters are missing :raises OperationPostponed: when an async operation is performed. """ consumer_query_manager = factory.consumer_query_manager() if consumer_query_manager.find_by_id(consumer_id) is None: raise MissingResource(consumer_id=consumer_id) consumer_criteria = Criteria(filters={'consumer_id': consumer_id}) task_tags = [ tags.action_tag('consumer_content_applicability_regeneration') ] async_result = regenerate_applicability_for_consumers.apply_async_with_reservation( tags.RESOURCE_CONSUMER_TYPE, consumer_id, (consumer_criteria.as_dict(), ), tags=task_tags) raise OperationPostponed(async_result)
def post(self, request, consumer_id): """ Creates an async task to regenerate content applicability data for given consumer. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :param consumer_id: The consumer ID. :type consumer_id: str :raises MissingResource: if some parameters are missing :raises OperationPostponed: when an async operation is performed. """ consumer_query_manager = factory.consumer_query_manager() if consumer_query_manager.find_by_id(consumer_id) is None: raise MissingResource(consumer_id=consumer_id) consumer_criteria = Criteria(filters={'consumer_id': consumer_id}) task_tags = [tags.action_tag('consumer_content_applicability_regeneration')] async_result = regenerate_applicability_for_consumers.apply_async_with_reservation( tags.RESOURCE_CONSUMER_TYPE, consumer_id, (consumer_criteria.as_dict(),), tags=task_tags) raise OperationPostponed(async_result)
def GET(self): params = web.input() manager = managers.consumer_query_manager() consumers = expand_consumers(params, manager.find_all()) for c in consumers: href = serialization.link.child_link_obj(c['id']) c.update(href) return self.ok(consumers)
def regenerate_applicability_for_consumers(consumer_criteria): """ Regenerate and save applicability data for given updated consumers. :param consumer_criteria: The consumer selection criteria :type consumer_criteria: dict """ consumer_criteria = Criteria.from_dict(consumer_criteria) consumer_query_manager = managers.consumer_query_manager() # Process consumer_criteria and get all the consumer ids satisfied by the criteria consumer_criteria.fields = ['id'] consumer_ids = [ c['id'] for c in consumer_query_manager.find_by_criteria(consumer_criteria) ] # Following logic of checking existing applicability and getting required data # to generate applicability is a bit more complicated than what it could be 'by design'. # It is to optimize the number of db queries and improving applicability generation # performance. Please consider the implications for applicability generation time # when making any modifications to this code. consumer_profile_map = ApplicabilityRegenerationManager._get_consumer_profile_map( consumer_ids) repo_consumer_map = ApplicabilityRegenerationManager._get_repo_consumer_map( consumer_ids=consumer_ids) # Since there could be different types of profiles and they are related (at the moment # these are RPMs and Modulemds in the RPM plugin), it's important to calculate applicability # not per profile but for a combination of all profiles of one consumer, # all_profiles_hash identifies that set of profiles. # Iterate through each unique all_profiles_hash and regenerate applicability, # if it doesn't exist. for repo_id in repo_consumer_map: seen_hashes = set() for consumer_id in repo_consumer_map[repo_id]: if consumer_id in consumer_profile_map: all_profiles_hash = consumer_profile_map[consumer_id][ 'all_profiles_hash'] if all_profiles_hash in seen_hashes: continue profiles = consumer_profile_map[consumer_id]['profiles'] seen_hashes.add(all_profiles_hash) if ApplicabilityRegenerationManager._is_existing_applicability( repo_id, all_profiles_hash): continue # If applicability does not exist, generate applicability data for given # profiles and repo id. ApplicabilityRegenerationManager.regenerate_applicability( all_profiles_hash, profiles, repo_id)
def get(self, request): """ List the available consumers. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :return: Response containing a list of consumers :rtype: django.http.HttpResponse """ query_params = request.GET manager = factory.consumer_query_manager() consumers = expand_consumers(query_params, manager.find_all()) for consumer in consumers: add_link(consumer) return generate_json_response_with_pulp_encoder(consumers)
def POST(self, consumer_id): """ Creates an async task to regenerate content applicability data for given consumer. :param consumer_id: The consumer ID. :type consumer_id: basestring """ consumer_query_manager = managers.consumer_query_manager() if consumer_query_manager.find_by_id(consumer_id) is None: raise MissingResource(consumer_id=consumer_id) consumer_criteria = Criteria(filters={'consumer_id': consumer_id}) task_tags = [tags.action_tag('consumer_content_applicability_regeneration')] async_result = regenerate_applicability_for_consumers.apply_async_with_reservation( tags.RESOURCE_CONSUMER_TYPE, consumer_id, (consumer_criteria.as_dict(),), tags=task_tags) raise OperationPostponed(async_result)
def regenerate_applicability_for_consumers(consumer_criteria): """ Regenerate and save applicability data for given updated consumers. :param consumer_criteria: The consumer selection criteria :type consumer_criteria: dict """ consumer_criteria = Criteria.from_dict(consumer_criteria) consumer_query_manager = managers.consumer_query_manager() bind_manager = managers.consumer_bind_manager() consumer_profile_manager = managers.consumer_profile_manager() # Process consumer_criteria and get all the consumer ids satisfied by the criteria consumer_criteria.fields = ['id'] consumer_ids = [c['id'] for c in consumer_query_manager.find_by_criteria(consumer_criteria)] # Following logic of checking existing applicability and getting required data # to generate applicability is a bit more complicated than what it could be 'by design'. # It is to optimize the number of db queries and improving applicability generation # performance. Please consider the implications for applicability generation time # when making any modifications to this code. # Get all unit profiles associated with given consumers unit_profile_criteria = Criteria( filters={'consumer_id': {'$in': consumer_ids}}, fields=['consumer_id', 'profile_hash', 'content_type', 'id']) all_unit_profiles = consumer_profile_manager.find_by_criteria(unit_profile_criteria) # Create a consumer-profile map with consumer id as the key and list of tuples # with profile details as the value consumer_unit_profiles_map = {} # Also create a map of profile_id keyed by profile_hash for profile lookup. profile_hash_profile_id_map = {} for unit_profile in all_unit_profiles: profile_hash = unit_profile['profile_hash'] content_type = unit_profile['content_type'] consumer_id = unit_profile['consumer_id'] profile_id = unit_profile['id'] profile_tuple = (profile_hash, content_type) # Add this tuple to the list of profile tuples for a consumer consumer_unit_profiles_map.setdefault(consumer_id, []).append(profile_tuple) # We need just one profile_id per profile_hash to be used in regenerate_applicability # method to get the actual profile corresponding to given profile_hash. if profile_hash not in profile_hash_profile_id_map: profile_hash_profile_id_map[profile_hash] = profile_id # Get all repos bound to given consumers bind_criteria = Criteria(filters={'consumer_id': {'$in': consumer_ids}}, fields=['repo_id', 'consumer_id']) all_repo_bindings = bind_manager.find_by_criteria(bind_criteria) # Create a repo-consumer map with repo_id as the key and consumer_id list as the value repo_consumers_map = {} for binding in all_repo_bindings: repo_consumers_map.setdefault(binding['repo_id'], []).append(binding['consumer_id']) # Create a set of (repo_id, (profile_hash, content_type)) repo_profile_hashes = set() for repo_id, consumer_id_list in repo_consumers_map.items(): for consumer_id in consumer_id_list: if consumer_id in consumer_unit_profiles_map: for unit_profile_tuple in consumer_unit_profiles_map[consumer_id]: repo_profile_hashes.add((repo_id, unit_profile_tuple)) # Iterate through each tuple in repo_profile_hashes set and regenerate applicability, # if it doesn't exist. These are all guaranteed to be unique tuples because of the logic # used to create maps and sets above, eliminating multiple unnecessary queries # to check for existing applicability for same profiles. manager = managers.applicability_regeneration_manager() for repo_id, (profile_hash, content_type) in repo_profile_hashes: # Check if applicability for given profile_hash and repo_id already exists if ApplicabilityRegenerationManager._is_existing_applicability(repo_id, profile_hash): continue # If applicability does not exist, generate applicability data for given profile # and repo id. profile_id = profile_hash_profile_id_map[profile_hash] manager.regenerate_applicability(profile_hash, content_type, profile_id, repo_id)
def regenerate_applicability_for_consumers(consumer_criteria): """ Regenerate and save applicability data for given updated consumers. :param consumer_criteria: The consumer selection criteria :type consumer_criteria: dict """ consumer_criteria = Criteria.from_dict(consumer_criteria) consumer_query_manager = managers.consumer_query_manager() bind_manager = managers.consumer_bind_manager() consumer_profile_manager = managers.consumer_profile_manager() # Process consumer_criteria and get all the consumer ids satisfied by the criteria consumer_criteria.fields = ['id'] consumer_ids = [ c['id'] for c in consumer_query_manager.find_by_criteria(consumer_criteria) ] # Following logic of checking existing applicability and getting required data # to generate applicability is a bit more complicated than what it could be 'by design'. # It is to optimize the number of db queries and improving applicability generation # performance. Please consider the implications for applicability generation time # when making any modifications to this code. # Get all unit profiles associated with given consumers unit_profile_criteria = Criteria( filters={'consumer_id': { '$in': consumer_ids }}, fields=['consumer_id', 'profile_hash', 'content_type', 'id']) all_unit_profiles = consumer_profile_manager.find_by_criteria( unit_profile_criteria) # Create a consumer-profile map with consumer id as the key and list of tuples # with profile details as the value consumer_unit_profiles_map = {} # Also create a map of profile_id keyed by profile_hash for profile lookup. profile_hash_profile_id_map = {} for unit_profile in all_unit_profiles: profile_hash = unit_profile['profile_hash'] content_type = unit_profile['content_type'] consumer_id = unit_profile['consumer_id'] profile_id = unit_profile['id'] profile_tuple = (profile_hash, content_type) # Add this tuple to the list of profile tuples for a consumer consumer_unit_profiles_map.setdefault(consumer_id, []).append(profile_tuple) # We need just one profile_id per profile_hash to be used in regenerate_applicability # method to get the actual profile corresponding to given profile_hash. if profile_hash not in profile_hash_profile_id_map: profile_hash_profile_id_map[profile_hash] = profile_id # Get all repos bound to given consumers bind_criteria = Criteria( filters={'consumer_id': { '$in': consumer_ids }}, fields=['repo_id', 'consumer_id']) all_repo_bindings = bind_manager.find_by_criteria(bind_criteria) # Create a repo-consumer map with repo_id as the key and consumer_id list as the value repo_consumers_map = {} for binding in all_repo_bindings: repo_consumers_map.setdefault(binding['repo_id'], []).append(binding['consumer_id']) # Create a set of (repo_id, (profile_hash, content_type)) repo_profile_hashes = set() for repo_id, consumer_id_list in repo_consumers_map.items(): for consumer_id in consumer_id_list: if consumer_id in consumer_unit_profiles_map: for unit_profile_tuple in consumer_unit_profiles_map[ consumer_id]: repo_profile_hashes.add((repo_id, unit_profile_tuple)) # Iterate through each tuple in repo_profile_hashes set and regenerate applicability, # if it doesn't exist. These are all guaranteed to be unique tuples because of the logic # used to create maps and sets above, eliminating multiple unnecessary queries # to check for existing applicability for same profiles. manager = managers.applicability_regeneration_manager() for repo_id, (profile_hash, content_type) in repo_profile_hashes: # Check if applicability for given profile_hash and repo_id already exists if ApplicabilityRegenerationManager._is_existing_applicability( repo_id, profile_hash): continue # If applicability does not exist, generate applicability data for given profile # and repo id. profile_id = profile_hash_profile_id_map[profile_hash] manager.regenerate_applicability(profile_hash, content_type, profile_id, repo_id)
def __init__(self): super(ConsumerSearch, self).__init__( managers.consumer_query_manager().find_by_criteria)
def find_applicable_units(self, consumer_criteria=None, repo_criteria=None, unit_criteria=None, override_config=None): """ Determine and report which of the content units specified by the unit_criteria are applicable to consumers specified by the consumer_criteria with repos specified by repo_criteria. If consumer_criteria is None, all consumers registered to the Pulp server are checked for applicability. If repo_criteria is None, all repos bound to the consumer are taken into consideration. If unit_criteria contains an empty list for a specific type, all units with specific type in the repos bound to the consumer are taken into consideration. :param consumer_criteria: The consumer selection criteria. :type consumer_criteria: dict :param repo_criteria: The repo selection criteria. :type repo_criteria: dict :param unit_criteria: A dictionary of type_id : unit selection criteria :type units: dict {<type_id1> : <unit_criteria_for_type_id1>, <type_id2> : <unit_criteria_for_type_id2>} :param override_config: Additional configuration options to be accepted from user :type override_config: dict :return: applicability reports dictionary keyed by content type id :rtype: dict """ result = {} conduit = ProfilerConduit() consumer_query_manager = managers.consumer_query_manager() bind_manager = managers.consumer_bind_manager() # Process Repo Criteria if repo_criteria: # Get repo ids satisfied by specified repo criteria repo_query_manager = managers.repo_query_manager() repo_criteria_ids = [r['id'] for r in repo_query_manager.find_by_criteria(repo_criteria)] # if repo_criteria is specified and there are no repos satisfying the criteria, return empty result if not repo_criteria_ids: return result else: repo_criteria_ids = None # Process Consumer Criteria if consumer_criteria: # Get consumer ids satisfied by specified consumer criteria consumer_ids = [c['id'] for c in consumer_query_manager.find_by_criteria(consumer_criteria)] else: if repo_criteria_ids: # If repo_criteria is specified, get all the consumers bound to the repos # satisfied by repo_criteria bind_criteria = Criteria(filters={"repo_id": {"$in": repo_criteria_ids}}) consumer_ids = [b['consumer_id'] for b in bind_manager.find_by_criteria(bind_criteria)] # Remove duplicate consumer ids consumer_ids = list(set(consumer_ids)) else: # Get all consumer ids registered to the Pulp server consumer_ids = [c['id'] for c in consumer_query_manager.find_all()] # if there are no relevant consumers, return empty result if not consumer_ids: return result else: # Based on the consumers, get all the repos bound to the consumers in consideration # and find intersection of repo_criteria_ids and consumer_repo_ids bind_criteria = Criteria(filters={"consumer_id": {"$in": consumer_ids}}) consumer_repo_ids = [b['repo_id'] for b in bind_manager.find_by_criteria(bind_criteria)] if not repo_criteria_ids: repo_criteria_ids = list(set(consumer_repo_ids)) else: repo_criteria_ids = list(set(consumer_repo_ids) & set(repo_criteria_ids)) if not repo_criteria_ids: return result # Process Unit Criteria if unit_criteria: # If unit_criteria is specified, get unit ids satisfied by the criteria for each content type # and save them in a dictionary keyed by the content type unit_ids_by_type = {} content_query_manager = managers.content_query_manager() for type_id, criteria in unit_criteria.items(): if criteria: criteria_ids = [u['_id'] for u in content_query_manager.find_by_criteria(type_id, criteria)] # If there are no units satisfied by the criteria, skip adding it to the dictionary if criteria_ids: unit_ids_by_type[type_id] = criteria_ids else: # If criteria for a content type id is None or empty dictionary, add it to the dictionary # with empty list as a value. This will be interpreted as all units of that specific type unit_ids_by_type[type_id] = [] else: # If unit_criteria is not specified set unit_ids_by_type to None to differentiate between # considering all units vs considering 0 units since no units were found satisfying given criteria unit_ids_by_type = None # Create a dictionary with consumer profile and repo_ids bound to the consumer keyed by consumer id consumer_profile_and_repo_ids = {} all_relevant_repo_ids = set() for consumer_id in consumer_ids: # Find repos bound to the consumer in consideration and find an intersection of bound repos to the # repos specified by repo_criteria consumer_bound_repo_ids = [b['repo_id'] for b in bind_manager.find_by_consumer(consumer_id)] consumer_bound_repo_ids = list(set(consumer_bound_repo_ids)) # If repo_criteria is not specified, use repos bound to the consumer, else take intersection # of repos specified in the criteria and repos bound to the consumer. if repo_criteria_ids is None: repo_ids = consumer_bound_repo_ids else: repo_ids = list(set(consumer_bound_repo_ids) & set(repo_criteria_ids)) if repo_ids: # Save all eligible repo ids to get relevant plugin unit keys when unit_criteria is not specified all_relevant_repo_ids = (all_relevant_repo_ids | set(repo_ids)) consumer_profile_and_repo_ids[consumer_id] = {'repo_ids': repo_ids} consumer_profile_and_repo_ids[consumer_id]['profiled_consumer'] = self.__profiled_consumer(consumer_id) # Get relevant units if unit_criteria is not specified units = self.__populate_units(unit_ids_by_type, list(all_relevant_repo_ids)) if units: # Call respective profiler api according to the unit type to check for applicability for typeid, unit_ids in units.items(): # if unit_ids is None or empty, continue to the next type id if not unit_ids: continue # Find a profiler for each type id and find units applicable using that profiler. profiler, cfg = self.__profiler(typeid) call_config = PluginCallConfiguration(plugin_config=cfg, repo_plugin_config=None, override_config=override_config) try: report_list = profiler.find_applicable_units(consumer_profile_and_repo_ids, typeid, unit_ids, call_config, conduit) except PulpExecutionException: report_list = None if report_list is None: _LOG.warn("Profiler for unit type [%s] is not returning applicability reports" % typeid) else: result[typeid] = report_list return result
def find_applicable_units(self, consumer_criteria=None, repo_criteria=None, unit_criteria=None, override_config=None): """ Determine and report which of the content units specified by the unit_criteria are applicable to consumers specified by the consumer_criteria with repos specified by repo_criteria. If consumer_criteria is None, all consumers registered to the Pulp server are checked for applicability. If repo_criteria is None, all repos bound to the consumer are taken into consideration. If unit_criteria contains an empty list for a specific type, all units with specific type in the repos bound to the consumer are taken into consideration. :param consumer_criteria: The consumer selection criteria. :type consumer_criteria: dict :param repo_criteria: The repo selection criteria. :type repo_criteria: dict :param unit_criteria: A dictionary of type_id : unit selection criteria :type units: dict {<type_id1> : <unit_criteria_for_type_id1>, <type_id2> : <unit_criteria_for_type_id2>} :param override_config: Additional configuration options to be accepted from user :type override_config: dict :return: applicability reports dictionary keyed by content type id :rtype: dict """ result = {} conduit = ProfilerConduit() consumer_query_manager = managers.consumer_query_manager() bind_manager = managers.consumer_bind_manager() # Process Repo Criteria if repo_criteria: # Get repo ids satisfied by specified repo criteria repo_query_manager = managers.repo_query_manager() repo_criteria_ids = [ r['id'] for r in repo_query_manager.find_by_criteria(repo_criteria) ] # if repo_criteria is specified and there are no repos satisfying the criteria, return empty result if not repo_criteria_ids: return result else: repo_criteria_ids = None # Process Consumer Criteria if consumer_criteria: # Get consumer ids satisfied by specified consumer criteria consumer_ids = [ c['id'] for c in consumer_query_manager.find_by_criteria( consumer_criteria) ] else: if repo_criteria_ids: # If repo_criteria is specified, get all the consumers bound to the repos # satisfied by repo_criteria bind_criteria = Criteria( filters={"repo_id": { "$in": repo_criteria_ids }}) consumer_ids = [ b['consumer_id'] for b in bind_manager.find_by_criteria(bind_criteria) ] # Remove duplicate consumer ids consumer_ids = list(set(consumer_ids)) else: # Get all consumer ids registered to the Pulp server consumer_ids = [ c['id'] for c in consumer_query_manager.find_all() ] # if there are no relevant consumers, return empty result if not consumer_ids: return result else: # Based on the consumers, get all the repos bound to the consumers in consideration # and find intersection of repo_criteria_ids and consumer_repo_ids bind_criteria = Criteria( filters={"consumer_id": { "$in": consumer_ids }}) consumer_repo_ids = [ b['repo_id'] for b in bind_manager.find_by_criteria(bind_criteria) ] if not repo_criteria_ids: repo_criteria_ids = list(set(consumer_repo_ids)) else: repo_criteria_ids = list( set(consumer_repo_ids) & set(repo_criteria_ids)) if not repo_criteria_ids: return result # Create a dictionary with consumer profile and repo_ids bound to the consumer keyed by consumer id consumer_profile_and_repo_ids = {} all_relevant_repo_ids = set() for consumer_id in consumer_ids: # Find repos bound to the consumer in consideration and find an intersection of bound repos to the # repos specified by repo_criteria consumer_bound_repo_ids = [ b['repo_id'] for b in bind_manager.find_by_consumer(consumer_id) ] consumer_bound_repo_ids = list(set(consumer_bound_repo_ids)) # If repo_criteria is not specified, use repos bound to the consumer, else take intersection # of repos specified in the criteria and repos bound to the consumer. if repo_criteria_ids is None: repo_ids = consumer_bound_repo_ids else: repo_ids = list( set(consumer_bound_repo_ids) & set(repo_criteria_ids)) if repo_ids: # Save all eligible repo ids to get relevant plugin unit keys when unit_criteria is not specified all_relevant_repo_ids = (all_relevant_repo_ids | set(repo_ids)) consumer_profile_and_repo_ids[consumer_id] = { 'repo_ids': repo_ids } consumer_profile_and_repo_ids[consumer_id][ 'profiled_consumer'] = self.__profiled_consumer( consumer_id) if not unit_criteria: return result # Call respective profiler api according to the unit type to check for applicability for unit_type_id, criteria in unit_criteria.items(): # Find a profiler for each type id and find units applicable using that profiler. profiler, cfg = self.__profiler(unit_type_id) call_config = PluginCallConfiguration( plugin_config=cfg, repo_plugin_config=None, override_config=override_config) try: report_list = profiler.find_applicable_units( consumer_profile_and_repo_ids, unit_type_id, criteria, call_config, conduit) except PulpExecutionException: report_list = None if report_list is None: _LOG.warn( "Profiler for unit type [%s] is not returning applicability reports" % unit_type_id) else: result[unit_type_id] = report_list return result
def units_applicable(self, consumer_criteria=None, repo_criteria=None, units=None): """ Determine and report which of the specified content units are applicable to consumers specified by the I{consumer_criteria} with repos specified by I{repo_criteria}. If consumer_criteria is None, all consumers registered to the Pulp server are checked for applicability. If repo_criteria is None, all repos bound to the consumer are taken into consideration. If units dictinary contains an empty list for a specific type, all units with specific type in the repos bound to the consumer are taken into consideration. Returns a dictionary with applicability reports for each unit keyed by a consumer id and further keyed by unit type id - {<consumer_id1>: { <unit_type_id1> : [<ApplicabilityReport>], <unit_type_id1> : [<ApplicabilityReport>]}, <consumer_id2>: { <unit_type_id1> : [<ApplicabilityReport>]} } :param consumer_criteria: The consumer selection criteria. :type consumer_criteria: dict :param repo_criteria: The repo selection criteria. :type repo_criteria: dict :param units: A dictionary of type_id : list of unit metadata :type units: dict {<type_id1> : [{<unit1_metadata>}, {<unit2_metadata>}, ..], <type_id2> : [{<unit1_metadata>}, {<unit2_metadata>}, ..]} :return: a dictionary with applicability reports for each unit keyed by a consumer id and further keyed by unit type id. See above for sample return report. :rtype: dict """ result = {} conduit = ProfilerConduit() # Get repo ids satisfied by specified consumer criteria if repo_criteria: repo_query_manager = managers.repo_query_manager() repo_criteria_ids = [r['id'] for r in repo_query_manager.find_by_criteria(repo_criteria)] else: repo_criteria_ids = None consumer_query_manager = managers.consumer_query_manager() bind_manager = managers.consumer_bind_manager() if consumer_criteria: # Get consumer ids satisfied by specified consumer criteria consumer_ids = [c['id'] for c in consumer_query_manager.find_by_criteria(consumer_criteria)] else: if repo_criteria_ids is not None: # If repo_criteria is specified, get all the consumers bound to the repos # satisfied by repo_criteria bind_criteria = {"filters": {"repo_id": {"$in": repo_criteria_ids}}} consumer_ids = [b['consumer_id'] for b in bind_manager.find_by_criteria(bind_criteria)] else: # Get all consumer ids registered to the Pulp server consumer_ids = [c['id'] for c in consumer_query_manager.find_all()] # Iterate through each consumer to collect applicability reports for consumer_id in consumer_ids: result[consumer_id] = {} # Find repos bound to a consumer bindings = bind_manager.find_by_consumer(consumer_id) bound_repo_ids = [b['repo_id'] for b in bindings] # If repo_criteria is not specified, use repos bound to the consumer, else take intersection # of repos specified in the criteria and repos bound to the consumer. if repo_criteria_ids is None: repo_ids = bound_repo_ids else: repo_ids = list(set(bound_repo_ids) & set(repo_criteria_ids)) plugin_unit_keys = self.__parse_units(units, repo_ids) if plugin_unit_keys: pc = self.__profiled_consumer(consumer_id) for typeid, unit_keys in plugin_unit_keys.items(): # Find a profiler for each type id and find units applicable using that profiler. profiler, cfg = self.__profiler(typeid) try: report_list = profiler.units_applicable(pc, repo_ids, typeid, unit_keys, cfg, conduit) except PulpExecutionException: report_list = None if report_list is not None: result[consumer_id][typeid] = report_list else: _LOG.warn("Profiler for unit type [%s] is not returning applicability reports" % typeid) return result