Exemplo n.º 1
0
    def modify(self, request, pk):
        """
        Queues a task that creates a new RepositoryVersion by adding and removing content units
        """
        add_content_units = {}
        remove_content_units = {}

        repository = self.get_object()
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        if "base_version" in request.data:
            base_version_pk = self.get_resource(request.data["base_version"],
                                                RepositoryVersion).pk
        else:
            base_version_pk = None

        if "add_content_units" in request.data:
            for url in request.data["add_content_units"]:
                add_content_units[NamedModelViewSet.extract_pk(url)] = url

            content_units_pks = set(add_content_units.keys())
            existing_content_units = Content.objects.filter(
                pk__in=content_units_pks)
            existing_content_units.touch()

            self.verify_content_units(existing_content_units,
                                      add_content_units)

            add_content_units = list(add_content_units.keys())

        if "remove_content_units" in request.data:
            if "*" in request.data["remove_content_units"]:
                remove_content_units = ["*"]
            else:
                for url in request.data["remove_content_units"]:
                    remove_content_units[NamedModelViewSet.extract_pk(
                        url)] = url
                content_units_pks = set(remove_content_units.keys())
                existing_content_units = Content.objects.filter(
                    pk__in=content_units_pks)
                self.verify_content_units(existing_content_units,
                                          remove_content_units)
                remove_content_units = list(remove_content_units.keys())

        task = dispatch(
            tasks.repository.add_and_remove,
            exclusive_resources=[repository],
            kwargs={
                "repository_pk": pk,
                "base_version_pk": base_version_pk,
                "add_content_units": add_content_units,
                "remove_content_units": remove_content_units,
            },
        )
        return OperationPostponedResponse(task, request)
Exemplo n.º 2
0
    def filter(self, qs, value):
        """
        Args:
            qs (django.db.models.query.QuerySet): The RepositoryVersion Queryset
            value (string): of content href to filter

        Returns:
            Queryset of the RepositoryVersions containing the specified content
        """

        if value is None:
            # user didn't supply a value
            return qs

        if not value:
            raise serializers.ValidationError(detail=_("No value supplied for content filter"))

        # Get the content object from the content_href
        content = NamedModelViewSet.get_resource(value, Content)

        # Get the repository from the parent request.
        repository_pk = self.parent.request.parser_context["kwargs"]["repository_pk"]
        repository = Repository.objects.get(pk=repository_pk)

        repository_content_set = RepositoryContent.objects.filter(
            content=content, repository=repository
        )

        # Get the sorted list of version_added and version_removed.
        version_added = list(repository_content_set.values_list("version_added__number", flat=True))

        # None values have to be filtered out from version_removed,
        # in order for zip_longest to pass it a default fillvalue
        version_removed = list(
            filter(
                None.__ne__,
                repository_content_set.values_list("version_removed__number", flat=True),
            )
        )

        # The range finding should work as long as both lists are sorted
        # Why it works: https://gist.github.com/werwty/6867f83ae5adbae71e452c28ecd9c444
        version_added.sort()
        version_removed.sort()

        # Match every version_added to a version_removed, if len(version_removed)
        # is shorter than len(version_added), pad out the remaining space with the current
        # repository version +1 (the +1 is to the current version gets included when we
        # calculate range)
        version_tuples = itertools.zip_longest(
            version_added, version_removed, fillvalue=repository.next_version
        )

        # Get the ranges between paired version_added and version_removed to get all
        # the versions the content is present in.
        versions = [list(range(added, removed)) for (added, removed) in version_tuples]
        # Flatten the list of lists
        versions = list(itertools.chain.from_iterable(versions))

        return qs.filter(number__in=versions)
Exemplo n.º 3
0
    def filter(self, qs, value):
        """
        Args:
            qs (django.db.models.query.QuerySet): The RepositoryVersion Queryset
            value (string): of content href to filter

        Returns:
            Queryset of the RepositoryVersions containing the specified content
        """

        if value is None:
            # user didn't supply a value
            return qs

        if not value:
            raise serializers.ValidationError(detail=_('No value supplied for content filter'))

        # Get the content object from the content_href
        content = NamedModelViewSet.get_resource(value, Content)

        # Get the repository from the parent request.
        repository_pk = self.parent.request.parser_context['kwargs']['repository_pk']
        repository = Repository.objects.get(pk=repository_pk)

        repository_content_set = RepositoryContent.objects.filter(content=content,
                                                                  repository=repository)

        # Get the sorted list of version_added and version_removed.
        version_added = list(repository_content_set.values_list('version_added__number', flat=True))

        # None values have to be filtered out from version_removed,
        # in order for zip_longest to pass it a default fillvalue
        version_removed = list(filter(None.__ne__, repository_content_set
                                      .values_list('version_removed__number', flat=True)))

        # The range finding should work as long as both lists are sorted
        # Why it works: https://gist.github.com/werwty/6867f83ae5adbae71e452c28ecd9c444
        version_added.sort()
        version_removed.sort()

        # Match every version_added to a version_removed, if len(version_removed)
        # is shorter than len(version_added), pad out the remaining space with the current
        # repository version +1 (the +1 is to the current version gets included when we
        # calculate range)
        version_tuples = itertools.zip_longest(version_added, version_removed,
                                               fillvalue=repository.last_version + 1)

        # Get the ranges between paired version_added and version_removed to get all
        # the versions the content is present in.
        versions = [list(range(added, removed)) for (added, removed) in version_tuples]
        # Flatten the list of lists
        versions = list(itertools.chain.from_iterable(versions))

        return qs.filter(number__in=versions)
Exemplo n.º 4
0
    def get_repository_version(value):
        """
        Get the repository version from the HREF value provided by the user.

        Args:
            value (string): The RepositoryVersion href to filter by
        """
        if not value:
            raise serializers.ValidationError(
                detail=_('No value supplied for repository version filter'))

        return NamedModelViewSet.get_resource(value, RepositoryVersion)
Exemplo n.º 5
0
    def filter(self, qs, value):
        if value is None:
            # user didn't supply a value
            return qs

        if not value:
            raise serializers.ValidationError(detail=_("No value supplied for content filter"))

        # Get the content object from the content_href
        content = NamedModelViewSet.get_resource(value, Content)

        return qs.with_content([content.pk])
Exemplo n.º 6
0
    def get_object_pk(self, request):
        """Return an object's pk from the request."""

        if "obj" not in request.data:
            raise ValidationError(_("Please provide 'obj' value"))

        obj_url = request.data["obj"]
        try:
            obj = NamedModelViewSet.get_resource(obj_url)
        except ValidationError:
            raise ValidationError(_("Invalid value for 'obj': {}.").format(obj_url))

        return obj.pk
Exemplo n.º 7
0
 def content_object_filter_function(self, queryset, name, value):
     if value == "null":
         return queryset.filter(object_id=None)
     else:
         try:
             obj = NamedModelViewSet.get_resource(value)
         except ValidationError:
             raise ValidationError(
                 _("Invalid value for 'content_object': {}.").format(value))
         obj_type = ContentType.objects.get_for_model(
             obj, for_concrete_model=False)
         return queryset.filter(content_type_id=obj_type.id,
                                object_id=obj.pk)
Exemplo n.º 8
0
    def filter(self, qs, value):
        """
        Args:
            qs (django.db.models.query.QuerySet): The QuerySet to filter
            value (string): The content href to filter by

        Returns:
            Queryset of the content contained within the specified created resource
        """

        if value is None:
            return qs

        match = resolve(value)
        resource = NamedModelViewSet.get_resource(value, match.func.cls.queryset.model)

        return qs.filter(created_resources__object_id=resource.pk)
Exemplo n.º 9
0
    def validate_content_hrefs(self, value):
        """
        Check that the content_hrefs is not an empty list and contains all valid hrefs.
        Args:
            value (list): The list supplied by the user
        Returns:
            The list of pks (not hrefs) after validation
        Raises:
            ValidationError: If the list is empty or contains invalid hrefs.
        """
        if len(value) == 0:
            raise serializers.ValidationError("Must not be [].")
        from pulpcore.app.viewsets import NamedModelViewSet

        pks_to_return = []
        for href in value:
            pks_to_return.append(NamedModelViewSet.get_resource(href, Content).pk)

        return pks_to_return
Exemplo n.º 10
0
    def filter(self, qs, value):
        """
        Args:
            qs (django.db.models.query.QuerySet): The RepositoryVersion Queryset
            value (string): of content href to filter

        Returns:
            Queryset of the RepositoryVersions containing the specified content
        """

        if value is None:
            # user didn't supply a value
            return qs

        if not value:
            raise serializers.ValidationError(
                detail=_("No value supplied for content filter"))

        # Get the content object from the content_href
        content = NamedModelViewSet.get_resource(value, Content)

        return qs.with_content([content.pk])