class ContentApplicabilityRegenerationView(View): """ Content applicability regeneration for updated repositories. """ @auth_required(authorization.CREATE) @parse_json_body(json_type=dict) def post(self, request): """ Dispatch a task to regenerate content applicability data for repositories that match the criteria passed in the body. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :raises exceptions.MissingValue: if repo_critera is not a body parameter :raises exceptions.InvalidValue: if repo_critera (dict) has unsupported keys, the manager will raise an InvalidValue for the specific keys. Here, we create a parent exception for repo_criteria and include the specific keys as child exceptions. :raises exceptions.OperationPostponed: dispatch a task """ class GroupCallReport(dict): def serialize(self): return self repo_criteria_body = request.body_as_json.get('repo_criteria', None) parallel = request.body_as_json.get('parallel', False) if repo_criteria_body is None: raise exceptions.MissingValue('repo_criteria') try: repo_criteria = Criteria.from_client_input(repo_criteria_body) except exceptions.InvalidValue, e: invalid_criteria = exceptions.InvalidValue('repo_criteria') invalid_criteria.add_child_exception(e) raise invalid_criteria if parallel: if type(parallel) is not bool: raise exceptions.InvalidValue('parallel') async_result = ApplicabilityRegenerationManager.\ queue_regenerate_applicability_for_repos(repo_criteria.as_dict()) ret = GroupCallReport() ret['group_id'] = str(async_result) ret['_href'] = reverse('task_group', kwargs={'group_id': str(async_result)}) raise exceptions.OperationPostponed(ret) regeneration_tag = tags.action_tag('content_applicability_regeneration') async_result = regenerate_applicability_for_repos.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_PROFILE_APPLICABILITY_TYPE, tags.RESOURCE_ANY_ID, (repo_criteria.as_dict(),), tags=[regeneration_tag]) raise exceptions.OperationPostponed(async_result)
def POST(self, repo_id): # Params (validation will occur in the manager) params = self.params() importer_type = params.get('importer_type_id', None) importer_config = params.get('importer_config', None) if importer_type is None: _logger.error( 'Missing importer type adding importer to repository [%s]' % repo_id) raise exceptions.MissingValue(['importer_type']) # Note: If an importer exists, it's removed, so no need to handle 409s. # Note: If the plugin raises an exception during initialization, let it # bubble up and be handled like any other 500. task_tags = [ tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, repo_id), tags.action_tag('add_importer') ] async_result = set_importer.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_TYPE, repo_id, [repo_id, importer_type], {'repo_plugin_config': importer_config}, tags=task_tags) raise exceptions.OperationPostponed(async_result)
def post(self, request, consumer_group_id): """ Create a bind association between the consumers belonging to the given consumer group by id included in the URL path and a repo-distributor specified in the POST body: {repo_id:<str>, distributor_id:<str>}. Designed to be idempotent so only MissingResource is expected to be raised by manager. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :param consumer_group_id: The consumer group ID to bind. :type consumer_group_id: str :raises: MissingResource if group id does not exist :raises: InvalidValue some parameters are invalid :raises: OperationPostponed when an async operation is performed """ params = request.body_as_json repo_id = params.get('repo_id') distributor_id = params.get('distributor_id') binding_config = params.get('binding_config', None) options = params.get('options', {}) notify_agent = params.get('notify_agent', True) missing_resources = verify_group_resources(consumer_group_id, repo_id, distributor_id) if missing_resources: if 'group_id' in missing_resources: raise pulp_exceptions.MissingResource(**missing_resources) else: raise pulp_exceptions.InvalidValue(list(missing_resources)) bind_args_tuple = (consumer_group_id, repo_id, distributor_id, notify_agent, binding_config, options) async_task = bind.apply_async(bind_args_tuple) raise pulp_exceptions.OperationPostponed(async_task)
def PUT(self, repo_id, importer_id): # Raise a MissingResource exception if the repo or the importer doesn't exist importer_manager = manager_factory.repo_importer_manager() importer = importer_manager.get_importer(repo_id) if importer['id'] != importer_id: raise exceptions.MissingResource(importer_id=importer_id) if not plugin_api.is_valid_importer(importer_id): raise exceptions.PulpCodedValidationException( error_code=error_codes.PLP1008) params = self.params() importer_config = params.get('importer_config', None) if importer_config is None: _logger.error( 'Missing configuration updating importer for repository [%s]' % repo_id) raise exceptions.MissingValue(['importer_config']) task_tags = [ tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, repo_id), tags.resource_tag(tags.RESOURCE_REPOSITORY_IMPORTER_TYPE, importer_id), tags.action_tag('update_importer') ] async_result = update_importer_config.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_TYPE, repo_id, [repo_id], {'importer_config': importer_config}, tags=task_tags) raise exceptions.OperationPostponed(async_result)
def POST(self, repo_id): """ Associate an importer with a repository. This will validate that the repository exists and that there is an importer with the importer_type_id given. However, the importer configuration validation only checks the provided values against a standard set of importer configuration keys. The importer specific validation is called on association, so any type specific configuration will be validated later. This means the spawned task could fail with a validation error. :param repo_id: the repository to associate the importer with :type repo_id: str """ params = self.params() importer_type = params.get('importer_type_id', None) config = params.get('importer_config', None) # This call will raise the appropriate exception importer_manager = manager_factory.repo_importer_manager() importer_manager.validate_importer_config(repo_id, importer_type, config) # Note: If an importer exists, it's removed, so no need to handle 409s. # Note: If the plugin raises an exception during initialization, let it # bubble up and be handled like any other 500. task_tags = [ tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, repo_id), tags.action_tag('add_importer') ] async_result = set_importer.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_TYPE, repo_id, [repo_id, importer_type], {'repo_plugin_config': config}, tags=task_tags) raise exceptions.OperationPostponed(async_result)
def put(self, request, repo_id, importer_id): """ Associate an importer to a repository. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :param repo_id: The id of the repository :type repo_id: str :param importer_id: The id of the importer to associate :type importer_id: str :raises exceptions.MissingValue: if required param importer_config is not in the body :raises exceptions.MissingResource: if importer does not match the repo's importer :raises exceptions.OperationPostponed: dispatch a task """ importer_controller.get_valid_importer(repo_id, importer_id) importer_config = request.body_as_json.get('importer_config', None) if importer_config is None: raise exceptions.MissingValue(['importer_config']) async_result = importer_controller.queue_update_importer_config(repo_id, importer_id, importer_config) raise exceptions.OperationPostponed(async_result)
def put(self, request, repo_id): """ Update a repository. This call will return synchronously unless a distributor is updated. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :param repo_id: id of repository to be updated :type repo_id: str :return: Response containing a serialized dict for the updated repo. :rtype : django.http.HttpResponse :raises exceptions.OperationPostponed: if a task has been dispatched to update a distributor """ delta = request.body_as_json.get('delta', None) importer_config = request.body_as_json.get('importer_config', None) distributor_configs = request.body_as_json.get('distributor_configs', None) repo = model.Repository.objects.get_repo_or_missing_resource(repo_id) task_result = repo_controller.update_repo_and_plugins(repo, delta, importer_config, distributor_configs) # Tasks are spawned if a distributor is updated, raise that as a result if task_result.spawned_tasks: raise exceptions.OperationPostponed(task_result) call_report = task_result.serialize() call_report['result'] = serializers.Repository(call_report['result']).data return generate_json_response_with_pulp_encoder(call_report)
def POST(self, repo_id): params = self.params() criteria = params.get('criteria', None) if criteria is not None: try: criteria = UnitAssociationCriteria.from_client_input(criteria) except: _logger.error('Error parsing unassociation criteria [%s]' % criteria) raise exceptions.PulpDataException(), None, sys.exc_info()[2] task_tags = [ tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, repo_id), tags.action_tag('unassociate') ] async_result = unassociate_by_criteria.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_TYPE, repo_id, [ repo_id, criteria, RepoContentUnit.OWNER_TYPE_USER, manager_factory.principal_manager().get_principal()['login'] ], tags=task_tags) raise exceptions.OperationPostponed(async_result)
class RepoImportUpload(View): """ View to import units into a repository. """ @auth_required(authorization.UPDATE) @json_body_required def post(self, request, repo_id): """ Import an uploaded unit into the given repository. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :param repo_id: The id of the repository the upload should be imported into :type repo_id: str :raises exceptions.OperationPostponed: dispatch a importy_uploaded_unit task """ try: upload_id = request.body_as_json['upload_id'] unit_type_id = request.body_as_json['unit_type_id'] unit_key = request.body_as_json['unit_key'] except KeyError, e: raise exceptions.MissingValue(e.args[0]) unit_metadata = request.body_as_json.pop('unit_metadata', None) override_config = request.body_as_json.pop('override_config', None) task_tags = [tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, repo_id), tags.action_tag('import_upload')] async_result = import_uploaded_unit.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_TYPE, repo_id, [repo_id, unit_type_id, unit_key, unit_metadata, upload_id, override_config], tags=task_tags) raise exceptions.OperationPostponed(async_result)
def POST(self, repo_id): """ Import an uploaded unit into the given repository. :param repo_id: The id of the repository the upload should be imported into :type repo_id: basestring :return: A json serialized dictionary with two keys. 'success_flag' indexes a boolean value that indicates whether the import was successful, and 'summary' will contain the summary as reported by the Importer. :rtype: basestring """ # Collect user input params = self.params() upload_id = params['upload_id'] unit_type_id = params['unit_type_id'] unit_key = params['unit_key'] unit_metadata = params.pop('unit_metadata', None) override_config = params.pop('override_config', None) task_tags = [ tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, repo_id), tags.action_tag('import_upload') ] async_result = import_uploaded_unit.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_TYPE, repo_id, [ repo_id, unit_type_id, unit_key, unit_metadata, upload_id, override_config ], tags=task_tags) raise exceptions.OperationPostponed(async_result)
class RepoUnassociate(View): """ View to unassociate a unit from a repository. """ @auth_required(authorization.UPDATE) @json_body_allow_empty def post(self, request, repo_id): """ Unassociate units that match the criteria from the given repository. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :param repo_id: id of the repository to unassociate content from :type repo_id: str :raises exceptions.InvalidValue: if criteria params cannot be parsed :raises exceptions.OperationPostponed: dispatch a unassociate_by_criteria task """ criteria_body = request.body_as_json.get('criteria', {}) try: criteria = UnitAssociationCriteria.from_client_input(criteria_body) except exceptions.InvalidValue, e: invalid_criteria = exceptions.InvalidValue('criteria') invalid_criteria.add_child_exception(e) raise invalid_criteria task_tags = [tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, repo_id), tags.action_tag('unassociate')] model.Repository.objects.get_repo_or_missing_resource(repo_id) async_result = unassociate_by_criteria.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_TYPE, repo_id, [repo_id, criteria.to_dict()], tags=task_tags) raise exceptions.OperationPostponed(async_result)
def POST(self, group_id): """ Create a bind association between the consumers belonging to the given consumer group by id included in the URL path and a repo-distributor specified in the POST body: {repo_id:<str>, distributor_id:<str>}. Designed to be idempotent so only MissingResource is expected to be raised by manager. :param group_id: The consumer group to bind. :type group_id: str :return: list of call requests :rtype: list """ body = self.params() repo_id = body.get('repo_id') distributor_id = body.get('distributor_id') binding_config = body.get('binding_config', None) options = body.get('options', {}) notify_agent = body.get('notify_agent', True) missing_resources = verify_group_resources(group_id, repo_id, distributor_id) if missing_resources: if 'group_id' in missing_resources: raise MissingResource(**missing_resources) else: raise InvalidValue(list(missing_resources)) bind_args_tuple = (group_id, repo_id, distributor_id, notify_agent, binding_config, options) async_task = bind.apply_async(bind_args_tuple) raise pulp_exceptions.OperationPostponed(async_task)
def post(self, request, repo_id): """ Dispatch a task to publish a repository. The JSON body may contain a key, `verify_all_units`, that forces the task to attempt to download all content units again rather than just those known to be not downloaded. :param request: WSGI request object. :type request: django.core.handlers.wsgi.WSGIRequest :param repo_id: id of the repository to publish. :type repo_id: str :raises pulp_exceptions.MissingResource: if repo does not exist. :raises pulp_exceptions.OperationPostponed: dispatch a ``download_repo`` task. """ model.Repository.objects.get_repo_or_missing_resource(repo_id) verify = request.body_as_json.get('verify_all_units', False) if not isinstance(verify, bool): raise exceptions.PulpCodedValidationException( error_code=exceptions.error_codes.PLP1010, value=verify, field='verify_all_units', field_type='boolean' ) async_result = content_controller.queue_download_repo(repo_id, verify_all_units=verify) raise exceptions.OperationPostponed(async_result)
def post(self, request, repo_group_id): """ Dispatch a task to publish content from the repo group using the distributor specified by the params. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :param repo_group_id: repo group to publish :type repo_group_id: str :raises pulp_exceptions.MissingValue if 'id' is not passed in the body :raises pulp_exceptions.OperationPosponed: dispatch a task """ params = request.body_as_json distributor_id = params.get('id', None) overrides = params.get('override_config', None) if distributor_id is None: raise pulp_exceptions.MissingValue(['id']) # If a repo group does not exist, get_group raises a MissingResource exception manager = managers_factory.repo_group_query_manager() manager.get_group(repo_group_id) task_tags = [ tags.resource_tag(tags.RESOURCE_REPOSITORY_GROUP_TYPE, repo_group_id), tags.resource_tag(tags.RESOURCE_REPOSITORY_GROUP_DISTRIBUTOR_TYPE, distributor_id), tags.action_tag('publish') ] async_result = repo_group_publish.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_GROUP_TYPE, repo_group_id, args=[repo_group_id, distributor_id], kwargs={'publish_config_override': overrides}, tags=task_tags) raise pulp_exceptions.OperationPostponed(async_result)
def POST(self, repo_id): # validation manager = manager_factory.repo_query_manager() manager.get_repository(repo_id) # Params params = self.params() distributor_id = params.get('id', None) overrides = params.get('override_config', None) async_result = repository.publish(repo_id, distributor_id, overrides) raise exceptions.OperationPostponed(async_result)
def DELETE(self, repo_id, importer_id): task_tags = [ tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, repo_id), tags.resource_tag(tags.RESOURCE_REPOSITORY_IMPORTER_TYPE, importer_id), tags.action_tag('delete_importer') ] async_result = remove_importer.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_TYPE, repo_id, [repo_id], tags=task_tags) raise exceptions.OperationPostponed(async_result)
def DELETE(self, repo_id): # validate manager_factory.repo_query_manager().get_repository(repo_id) # delete task_tags = [ tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, repo_id), tags.action_tag('delete') ] async_result = repository.delete.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_TYPE, repo_id, [repo_id], tags=task_tags) raise exceptions.OperationPostponed(async_result)
def POST(self, repo_id): # Params params = self.params() overrides = params.get('override_config', None) # Check for repo existence and let the missing resource bubble up manager_factory.repo_query_manager().get_repository(repo_id) # Execute the sync asynchronously async_result = repository.sync_with_auto_publish(repo_id, overrides) # this raises an exception that is handled by the middleware, # so no return is needed raise exceptions.OperationPostponed(async_result)
class RepoAssociate(View): """ View to copy units between repositories. """ @auth_required(authorization.UPDATE) @json_body_required def post(self, request, dest_repo_id): """ Associate units matching the criteria into the given repository :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :param dest_repo_id: id of the repository content will be copied to :type dest_repo_id: str :raises exceptions.MissingValue: if required param source_repo_id is not passed :raises exceptions.InvalidValue: if source_repo_id is not found or if criteria params cannot be parsed :raises exceptions.OperationPostponed: dispatch a publish repo task """ model.Repository.objects.get_repo_or_missing_resource(dest_repo_id) criteria_body = request.body_as_json.get('criteria', {}) overrides = request.body_as_json.get('override_config', None) source_repo_id = request.body_as_json.get('source_repo_id', None) if source_repo_id is None: raise exceptions.MissingValue(['source_repo_id']) # Catch MissingResource because this is body data, raise 400 rather than 404 try: model.Repository.objects.get_repo_or_missing_resource(source_repo_id) except exceptions.MissingResource: raise exceptions.InvalidValue(['source_repo_id']) try: criteria = UnitAssociationCriteria.from_client_input(criteria_body) except exceptions.InvalidValue, e: invalid_criteria = exceptions.InvalidValue('criteria') invalid_criteria.add_child_exception(e) raise invalid_criteria task_tags = [tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, dest_repo_id), tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, source_repo_id), tags.action_tag('associate')] async_result = associate_from_repo.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_TYPE, dest_repo_id, [source_repo_id, dest_repo_id], {'criteria': criteria.to_dict(), 'import_config_override': overrides}, tags=task_tags) raise exceptions.OperationPostponed(async_result)
def update(self, consumer_group_id): """ Update content (units) on the consumer in a consumer group. Expected body: {units:[], options:<dict>} where unit is: {type_id:<str>, unit_key={}} and the options is a dict of update options. @param consumer_group_id: A consumer group ID. @type consumer_group_id: str @return: list of call requests @rtype: list """ body = self.params() units = body.get('units') options = body.get('options') task = consumer_group.update_content(consumer_group_id, units, options) raise pulp_exceptions.OperationPostponed(task)
def delete(self, request, repo_id): """ Dispatch a task to delete a repository. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :param repo_id: id of repository to be removed :type repo_id: str :rtype : django.http.HttpResponse :raises exceptions.MissingResource: if repo does not exist :raises exceptions.OperationPostponed: dispatch a task to delete the provided repo """ model.Repository.objects.get_repo_or_missing_resource(repo_id) async_result = repo_controller.queue_delete(repo_id) raise exceptions.OperationPostponed(async_result)
def delete(self, request, repo_id, distributor_id): """ Disassociate the requested distributor. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :param repo_id: The id of the repository the to disassociate from :type repo_id: basestring :param repo_id: The id of the distributor to disassociate :type repo_id: basestring :raises exceptions.OperationPostponed: dispatch a task """ dist = model.Distributor.objects.get_or_404(repo_id=repo_id, distributor_id=distributor_id) async_result = dist_controller.queue_delete(dist) raise exceptions.OperationPostponed(async_result)
def delete(self, request, repo_id, importer_id): """ Dispatch a task to remove an importer from a repository. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :param repo_id: The id of the repository to remove the importer from :type repo_id: str :param importer_id: The id of the importer to remove from the given repository :type importer_id: str :raises exceptions.OperationPostponed: to dispatch a task to delete the importer """ importer_controller.get_valid_importer(repo_id, importer_id) async_result = importer_controller.queue_remove_importer(repo_id, importer_id) raise exceptions.OperationPostponed(async_result)
def post(self, request, repo_id): """ Dispatch a task to sync a repository. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :param repo_id: id of the repository to sync :type repo_id: str :raises exceptions.OperationPostponed: dispatch a sync repo task """ overrides = request.body_as_json.get('override_config', None) model.Repository.objects.get_repo_or_missing_resource(repo_id) async_result = repo_controller.queue_sync_with_auto_publish(repo_id, overrides) raise exceptions.OperationPostponed(async_result)
def uninstall(self, consumer_group_id): """ Uninstall content (units) from the consumers in a consumer group. Expected body: {units:[], options:<dict>} where unit is: {type_id:<str>, unit_key={}} and the options is a dict of uninstall options. @param consumer_group_id: A consumer group ID. @type consumer_group_id: str @return: list of call requests @rtype: list """ body = self.params() units = body.get('units') options = body.get('options') task = managers_factory.consumer_group_manager().uninstall_content( consumer_group_id, units, options) raise pulp_exceptions.OperationPostponed(task)
def DELETE(self, repo_id, distributor_id): # validate resources manager = manager_factory.repo_distributor_manager() manager.get_distributor(repo_id, distributor_id) # delete task_tags = [ tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, repo_id), tags.resource_tag(tags.RESOURCE_REPOSITORY_DISTRIBUTOR_TYPE, distributor_id), tags.action_tag('remove_distributor') ] async_result = repository.distributor_delete.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_TYPE, repo_id, [repo_id, distributor_id], tags=task_tags) raise exceptions.OperationPostponed(async_result)
def DELETE(self, group_id, repo_id, distributor_id): """ Delete a bind association between the specified consumer and repo-distributor. Designed to be idempotent. @param group_id: A consumer group ID. @type group_id: str @param repo_id: A repo ID. @type repo_id: str @param distributor_id: A distributor ID. @type distributor_id: str @return: The deleted bind model object: {consumer_group_id:<str>, repo_id:<str>, distributor_id:<str>} Or, None if bind does not exist. @rtype: dict """ async_task = consumer_group.unbind.apply_async( (group_id, repo_id, distributor_id, {})) raise pulp_exceptions.OperationPostponed(async_task)
class ContentApplicabilityRegenerationView(View): """ Content applicability regeneration for updated repositories. """ @auth_required(authorization.CREATE) @json_body_required def post(self, request): """ Dispatch a task to regenerate content applicability data for repositories that match the criteria passed in the body. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :raises exceptions.MissingValue: if repo_critera is not a body parameter :raises exceptions.InvalidValue: if repo_critera (dict) has unsupported keys, the manager will raise an InvalidValue for the specific keys. Here, we create a parent exception for repo_criteria and include the specific keys as child exceptions. :raises exceptions.OperationPostponed: dispatch a task """ class GroupCallReport(dict): def serialize(self): return self repo_criteria_body = request.body_as_json.get('repo_criteria', None) if repo_criteria_body is None: raise exceptions.MissingValue('repo_criteria') try: repo_criteria = Criteria.from_client_input(repo_criteria_body) except exceptions.InvalidValue, e: invalid_criteria = exceptions.InvalidValue('repo_criteria') invalid_criteria.add_child_exception(e) raise invalid_criteria async_result = ApplicabilityRegenerationManager.queue_regenerate_applicability_for_repos( repo_criteria.as_dict()) ret = GroupCallReport() ret['group_id'] = str(async_result) ret['_href'] = reverse('task_group', kwargs={'group_id': str(async_result)}) raise exceptions.OperationPostponed(ret)
def POST(self, dest_repo_id): # Params params = self.params() source_repo_id = params.get('source_repo_id', None) overrides = params.get('override_config', None) if source_repo_id is None: raise exceptions.MissingValue(['source_repo_id']) # A 404 only applies to things in the URL, so the destination repo # check allows the MissingResource to bubble up, but if the source # repo doesn't exist, it's considered bad data. repo_query_manager = manager_factory.repo_query_manager() repo_query_manager.get_repository(dest_repo_id) try: repo_query_manager.get_repository(source_repo_id) except exceptions.MissingResource: raise exceptions.InvalidValue(['source_repo_id']) criteria = params.get('criteria', None) if criteria is not None: try: criteria = UnitAssociationCriteria.from_client_input(criteria) except: _logger.error('Error parsing association criteria [%s]' % criteria) raise exceptions.PulpDataException(), None, sys.exc_info()[2] task_tags = [ tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, dest_repo_id), tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, source_repo_id), tags.action_tag('associate') ] async_result = associate_from_repo.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_TYPE, dest_repo_id, [source_repo_id, dest_repo_id], { 'criteria': criteria, 'import_config_override': overrides }, tags=task_tags) raise exceptions.OperationPostponed(async_result)
def uninstall(self, request, consumer_group_id): """ Uninstall content (units) from the consumers in a consumer group. Expected body: {units:[], options:<dict>} where unit is: {type_id:<str>, unit_key={}} and the options is a dict of uninstall options. :param request: WSGI request object :type request: django.core.handlers.wsgi.WSGIRequest :param consumer_group_id: A consumer group ID. :type consumer_group_id: str :raises: OperationPostponed when an async operation is performed """ body = request.body_as_json units = body.get('units') options = body.get('options') task = factory.consumer_group_manager().uninstall_content( consumer_group_id, units, options) raise pulp_exceptions.OperationPostponed(task)