Exemple #1
0
    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)
Exemple #2
0
def validate_importer_config(repo_obj, importer_type_id, config):
    """
    Validates the importer configuration.

    :param repo_obj: repository object
    :type  repo_obj: pulp.server.db.model.Repository
    :param importer_type_id: type of importer, must correspond to a plugin loaded at server startup
    :type  importer_type_id: str
    :param config: configuration values for the importer
    :type  config: dict

    :raises PulpCodedValidationException: if importer_type_id is invalid
    :raises exceptions.PulpDataException: if config is invalid.
    """
    if not plugin_api.is_valid_importer(importer_type_id):
        raise exceptions.PulpCodedValidationException(
            error_code=error_codes.PLP1008, importer_type_id=importer_type_id)

    importer_instance, plugin_config = plugin_api.get_importer_by_id(
        importer_type_id)
    call_config = PluginCallConfiguration(plugin_config, config)
    transfer_repo = repo_obj.to_transfer_repo()
    result = importer_instance.validate_config(transfer_repo, call_config)

    # For backward compatibility with plugins that don't yet return the tuple
    if isinstance(result, bool):
        valid_config = result
        message = None
    else:
        valid_config, message = result

    if not valid_config:
        raise exceptions.PulpDataException(message)
Exemple #3
0
    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)
Exemple #4
0
def update_repo_and_plugins(repo, repo_delta, importer_config, distributor_configs):
    """
    Update a reposiory and its related collections.

    All details do not need to be specified; if a piece is omitted it's configuration is not
    touched, nor is it removed from the repository. The same holds true for the distributor_configs
    dict, not every distributor must be represented.

    This call will attempt to update the repository object, then the importer, then the
    distributors. If an exception occurs during any of these steps, the updates stop and the
    exception is immediately raised. Any updates that have already taken place are not rolled back.

    Distributor updates are asynchronous as there could be a very large number of consumers to
    update. Repository and importer updates are done synchronously.

    :param repo: repository object
    :type  repo: pulp.server.db.model.Repository
    :param repo_delta: list of attributes to change and their new values; if None, no attempt to
                       update the repository object will be made
    :type  repo_delta: dict, None
    :param importer_config: new configuration to use for the repo's importer; if None, no attempt
                            will be made to update the importer
    :type  importer_config: dict, None
    :param distributor_configs: mapping of distributor ID to the new configuration to set for it
    :type  distributor_configs: dict, None

    :return: Task result that contains the updated repository object and additional spawned tasks
    :rtype:  pulp.server.async.tasks.TaskResult

    :raises pulp_exceptions.InvalidValue: if repo_delta is not a dictionary
    """
    if repo_delta:
        if isinstance(repo_delta, dict):
            repo.update_from_delta(repo_delta)
            repo.save()
        else:
            raise pulp_exceptions.PulpCodedValidationException(
                error_code=error_codes.PLP1010, field='delta', field_type='dict', value=repo_delta)

    if importer_config is not None:
        importer_controller.update_importer_config(repo.repo_id, importer_config)

    additional_tasks = []
    if distributor_configs is not None:
        for dist_id, dist_config in distributor_configs.items():
            task_tags = [
                tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, repo.repo_id),
                tags.resource_tag(tags.RESOURCE_REPOSITORY_DISTRIBUTOR_TYPE,
                                  dist_id),
                tags.action_tag(tags.ACTION_UPDATE_DISTRIBUTOR)
            ]
            async_result = dist_controller.update.apply_async_with_reservation(
                tags.RESOURCE_REPOSITORY_TYPE, repo.repo_id,
                [repo.repo_id, dist_id, dist_config, None], tags=task_tags)
            additional_tasks.append(async_result)
    return TaskResult(repo, None, additional_tasks)
Exemple #5
0
def set_importer(repo_id, importer_type_id, repo_plugin_config):
    """
    Configures an importer to be used for the given repository.

    :param repo: repository object that the importer should be associated with
    :type  repo: pulp.server.db.model.Repository
    :param importer_type_id: type of importer, must correspond to a plugin loaded at server startup
    :type  importer_type_id: str
    :param repo_plugin_config: configuration values for the importer; may be None
    :type  repo_plugin_config: dict or None

    :return: key-value pairs describing the importer that was set
    :rtype:  dict

    :raises PulpExecutionException: if something goes wrong in the plugin
    :raises exceptions.InvalidValue: if the values passed to create the importer are invalid
    """
    repo = model.Repository.objects.get_repo_or_missing_resource(repo_id)

    if not plugin_api.is_valid_importer(importer_type_id):
        raise exceptions.PulpCodedValidationException(
            error_code=error_codes.PLP1008, importer_type_id=importer_type_id)

    importer_instance, plugin_config = plugin_api.get_importer_by_id(
        importer_type_id)
    clean_config = clean_config_dict(repo_plugin_config)

    # Let the importer plugin verify the configuration
    call_config = PluginCallConfiguration(plugin_config, clean_config)
    transfer_repo = repo.to_transfer_repo()
    validate_importer_config(repo, importer_type_id, clean_config)

    try:
        remove_importer(repo_id)
    except exceptions.MissingResource:
        pass  # it didn't exist, so no harm done

    # Let the importer plugin initialize the importer
    try:
        importer_instance.importer_added(transfer_repo, call_config)
    except Exception:
        _logger.exception('Error initializing importer [%s] for repo [%s]' %
                          (importer_type_id, repo.repo_id))
        raise exceptions.PulpExecutionException(), None, sys.exc_info()[2]

    importer = model.Importer(repo_id, importer_type_id, clean_config)
    try:
        importer.save()
    except ValidationError, e:
        raise exceptions.InvalidValue(e.to_dict().keys())
Exemple #6
0
    def create_consumer_group(group_id, display_name=None, description=None, consumer_ids=None,
                              notes=None):
        """
        Create a new consumer group.

        :param group_id:     unique id of the consumer group
        :type  group_id:     str
        :param display_name: display name of the consumer group
        :type  display_name: str or None
        :param description:  description of the consumer group
        :type  description:  str or None
        :param consumer_ids: list of ids for consumers initially belonging to the consumer group
        :type  consumer_ids: list or None
        :param notes:        notes for the consumer group
        :type  notes:        dict or None
        :return:             SON representation of the consumer group
        :rtype:              bson.SON
        """
        validation_errors = []
        if group_id is None:
            validation_errors.append(PulpCodedException(error_codes.PLP1002, field='group_id'))
        elif _CONSUMER_GROUP_ID_REGEX.match(group_id) is None:
            validation_errors.append(PulpCodedException(error_codes.PLP1003, field='group_id'))

        if consumer_ids:
            # Validate that all the consumer_ids exist and raise an exception if they don't
            consumer_collection = Consumer.get_collection()
            matched_consumers = consumer_collection.find({'id': {'$in': consumer_ids}})
            if matched_consumers.count() is not len(consumer_ids):
                # Create a set of all the matched consumer_ids
                matched_consumers_set = set()
                for consumer in matched_consumers:
                    matched_consumers_set.add(consumer.get('id'))
                # find the missing items
                for consumer_id in (set(consumer_ids)).difference(matched_consumers_set):
                    validation_errors.append(PulpCodedException(error_codes.PLP1001,
                                                                consumer_id=consumer_id))

        if validation_errors:
            raise pulp_exceptions.PulpCodedValidationException(validation_errors)

        collection = ConsumerGroup.get_collection()
        consumer_group = ConsumerGroup(group_id, display_name, description, consumer_ids, notes)
        try:
            collection.insert(consumer_group)
        except DuplicateKeyError:
            raise pulp_exceptions.DuplicateResource(group_id), None, sys.exc_info()[2]

        group = collection.find_one({'id': group_id})
        return group
Exemple #7
0
def validate_importer_config(repo_id, importer_type_id, importer_config):
    """
    This validates that the repository and importer type exist as these are both required to
    validate the configuration.

    :param repo_id: identifies the repo
    :type  repo_id: str
    :param importer_type_id: type of importer, must correspond to a plugin loaded at server startup
    :type  importer_type_id: str
    :param importer_config: configuration values for the importer; may be None
    :type  importer_config: dict

    :raises exceptions.PulpCodedValidationException: if config is invalid.
    """
    repo_obj = model.Repository.objects.get_repo_or_missing_resource(repo_id)

    if not plugin_api.is_valid_importer(importer_type_id):
        raise exceptions.PulpCodedValidationException(
            error_code=error_codes.PLP1008, importer_type_id=importer_type_id)

    importer_instance, plugin_config = plugin_api.get_importer_by_id(
        importer_type_id)
    clean_config = clean_config_dict(importer_config)
    call_config = PluginCallConfiguration(plugin_config, clean_config)
    transfer_repo = repo_obj.to_transfer_repo()
    result = importer_instance.validate_config(transfer_repo, call_config)

    # For backward compatibility with plugins that don't yet return the tuple
    if isinstance(result, bool):
        valid_config = result
        message = None
    else:
        valid_config, message = result

    if not valid_config:
        raise exceptions.PulpCodedValidationException(
            validation_errors=message)
Exemple #8
0
    def delete(self, request):
        """
        Delete the tasks with status as finished, error, timed-out and skipped

        :param request: WSGI request object
        :type  request: django.core.handlers.wsgi.WSGIRequest

        :return: Response containing None or pulp Exception
        :rtype:  django.http.HttpResponse or pulp.Exception
        """
        task_state = request.GET.getlist('state')
        if not task_state:
            raise pulp_exceptions.PulpCodedForbiddenException(error_code=error_codes.PLP1012)

        for state in task_state:
            if state not in VALID_STATES:
                raise pulp_exceptions.PulpCodedValidationException(
                    error_code=error_codes.PLP1011, state=state)

        for state in task_state:
                TaskStatus.objects(state=state).delete()

        return HttpResponse(status=204)
Exemple #9
0
 def test_init(self):
     """
     Test basic init with no values
     """
     e = exceptions.PulpCodedValidationException()
     self.assertEquals(e.error_code, error_codes.PLP1000)