Пример #1
0
class RepositoryVersionCreateSerializer(ModelSerializer,
                                        NestedHyperlinkedModelSerializer):
    add_content_units = serializers.ListField(help_text=_(
        'A list of content units to add to a new repository version. This content is '
        'added after remove_content_units are removed.'),
                                              write_only=True,
                                              required=False)
    remove_content_units = serializers.ListField(help_text=_(
        "A list of content units to remove from the latest repository version. "
        "You may also specify '*' as an entry to remove all content. This content is "
        "removed before add_content_units are added."),
                                                 write_only=True,
                                                 required=False)
    base_version = NestedRelatedField(
        required=False,
        help_text=_(
            'A repository version whose content will be used as the initial set of content '
            'for the new repository version'),
        queryset=models.RepositoryVersion.objects.all(),
        view_name='versions-detail',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
    )

    def validate_remove_content_units(self, value):
        if len(value) > 1 and '*' in value:
            raise serializers.ValidationError(
                "Cannot supply content units and '*'.")
        return value

    class Meta:
        model = models.RepositoryVersion
        fields = ['add_content_units', 'remove_content_units', 'base_version']
Пример #2
0
class RepositoryVersionDistributionSerializer(BaseDistributionSerializer):
    repository = RelatedField(
        required=False,
        help_text=_('The latest RepositoryVersion for this Repository will be served.'),
        queryset=models.Repository.objects.all(),
        view_name='repositories-detail',
        allow_null=True
    )
    repository_version = NestedRelatedField(
        required=False,
        help_text=_('RepositoryVersion to be served'),
        queryset=models.RepositoryVersion.objects.exclude(complete=False),
        view_name='versions-detail',
        allow_null=True,
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
    )

    class Meta:
        abstract = True
        fields = BaseDistributionSerializer.Meta.fields + (
            'repository',
            'repository_version',
        )

    def validate(self, data):
        super().validate(data)

        if 'repository' in data and 'repository_version' in data:
            msg = _("The attributes 'repository' and 'repository_version' must be used"
                    "exclusively.")
            raise serializers.ValidationError(msg)

        return data
Пример #3
0
class RepositoryVersionSerializer(ModelSerializer,
                                  NestedHyperlinkedModelSerializer):
    pulp_href = NestedIdentityField(
        view_name='versions-detail',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
    )
    number = serializers.IntegerField(read_only=True)
    base_version = NestedRelatedField(
        required=False,
        help_text=_(
            'A repository version whose content was used as the initial set of content '
            'for this repository version'),
        queryset=models.RepositoryVersion.objects.all(),
        view_name='versions-detail',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
    )
    content_summary = ContentSummarySerializer(
        help_text=_(
            'Various count summaries of the content in the version and the HREF to view '
            'them.'),
        source="*",
        read_only=True,
    )

    class Meta:
        model = models.RepositoryVersion
        fields = ModelSerializer.Meta.fields + (
            'pulp_href',
            'number',
            'base_version',
            'content_summary',
        )
Пример #4
0
class PublicationSerializer(ModelSerializer):
    _href = IdentityField(
        view_name='publications-detail'
    )
    pass_through = serializers.BooleanField(
        help_text=_('The publication is a pass-through for the repository version.')
    )
    publisher = DetailRelatedField(
        help_text=_('The publisher that created this publication.'),
        queryset=models.Publisher.objects.all()
    )
    distributions = serializers.HyperlinkedRelatedField(
        help_text=_('This publication is currently being served as'
                    'defined by these distributions.'),
        many=True,
        read_only=True,
        view_name='distributions-detail',
    )
    repository_version = NestedRelatedField(
        view_name='versions-detail',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
        read_only=True,
    )

    class Meta:
        model = models.Publication
        fields = ModelSerializer.Meta.fields + (
            'pass_through',
            'publisher',
            'distributions',
            'repository_version',
        )
Пример #5
0
class RepositoryVersionSerializer(ModelSerializer,
                                  NestedHyperlinkedModelSerializer):
    _href = NestedIdentityField(
        view_name='versions-detail',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
    )
    number = serializers.IntegerField(read_only=True)
    base_version = NestedRelatedField(
        required=False,
        help_text=_(
            'A repository version whose content was used as the initial set of content '
            'for this repository version'),
        queryset=models.RepositoryVersion.objects.all(),
        view_name='versions-detail',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
    )
    content_summary = serializers.SerializerMethodField(
        help_text=_(
            'Various count summaries of the content in the version and the HREF to view '
            'them.'),
        read_only=True,
    )

    def get_content_summary(self, obj):
        """
        The summary of contained content.

        Returns:
            dict: The dictionary has the following format.::

                {
                    'added': {<_type>: {'count': <count>, 'href': <href>},
                    'removed': {<_type>: {'count': <count>, 'href': <href>},
                    'present': {<_type>: {'count': <count>, 'href': <href>},
                }

        """
        to_return = {'added': {}, 'removed': {}, 'present': {}}
        for count_detail in obj.counts.all():
            count_type = count_detail.get_count_type_display()
            item_dict = {
                'count': count_detail.count,
                'href': count_detail.content_href
            }
            to_return[count_type][count_detail.content_type] = item_dict
        return to_return

    class Meta:
        model = models.RepositoryVersion
        fields = ModelSerializer.Meta.fields + (
            '_href',
            'number',
            'base_version',
            'content_summary',
        )
Пример #6
0
class PublicationSerializer(MasterModelSerializer):
    _href = DetailIdentityField()
    repository_version = NestedRelatedField(
        view_name='versions-detail',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
        queryset=models.RepositoryVersion.objects.all(),
        required=False,
    )
    repository = RelatedField(
        help_text=_('A URI of the repository to be published.'),
        required=False,
        label=_('Repository'),
        queryset=models.Repository.objects.all(),
        view_name='repositories-detail',
        write_only=True
    )

    def validate(self, data):
        if hasattr(self, 'initial_data'):
            validate_unknown_fields(self.initial_data, self.fields)

        repository = data.pop('repository', None)  # not an actual field on publication
        repository_version = data.get('repository_version')
        if not repository and not repository_version:
            raise serializers.ValidationError(
                _("Either the 'repository' or 'repository_version' need to be specified"))
        elif not repository and repository_version:
            return data
        elif repository and not repository_version:
            version = models.RepositoryVersion.latest(repository)
            if version:
                new_data = {'repository_version': version}
                new_data.update(data)
                return new_data
            else:
                raise serializers.ValidationError(
                    detail=_('Repository has no version available to create Publication from'))
        raise serializers.ValidationError(
            _("Either the 'repository' or 'repository_version' need to be specified "
              "but not both.")
        )

    class Meta:
        abstract = True
        model = models.Publication
        fields = MasterModelSerializer.Meta.fields + (
            'publisher',
            'repository_version',
            'repository'
        )
Пример #7
0
class RepositoryPublishURLSerializer(serializers.Serializer):

    repository = serializers.HyperlinkedRelatedField(
        help_text=_('A URI of the repository to be synchronized.'),
        required=False,
        label=_('Repository'),
        queryset=models.Repository.objects.all(),
        view_name='repositories-detail',
    )

    repository_version = NestedRelatedField(
        help_text=_('A URI of the repository version to be published.'),
        required=False,
        label=_('Repository Version'),
        queryset=models.RepositoryVersion.objects.all(),
        view_name='versions-detail',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
    )

    def validate(self, data):
        if hasattr(self, 'initial_data'):
            validate_unknown_fields(self.initial_data, self.fields)

        repository = data.pop('repository', None)
        repository_version = data.get('repository_version')
        if not repository and not repository_version:
            raise serializers.ValidationError(
                _("Either the 'repository' or 'repository_version' need to be specified"
                  ))
        elif not repository and repository_version:
            return data
        elif repository and not repository_version:
            version = models.RepositoryVersion.latest(repository)
            if version:
                new_data = {'repository_version': version}
                new_data.update(data)
                return new_data
            else:
                raise serializers.ValidationError(
                    detail=_('Repository has no version available to publish'))
        raise serializers.ValidationError(
            _("Either the 'repository' or 'repository_version' need to be specified "
              "but not both."))
Пример #8
0
class RepositoryVersionSerializer(ModelSerializer,
                                  NestedHyperlinkedModelSerializer):
    _href = NestedIdentityField(
        view_name='versions-detail',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
    )
    _content_href = NestedIdentityField(
        view_name='versions-content',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
    )
    _added_href = NestedIdentityField(
        view_name='versions-added-content',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
    )
    _removed_href = NestedIdentityField(
        view_name='versions-removed-content',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
    )
    number = serializers.IntegerField(read_only=True)
    content_summary = serializers.DictField(help_text=_(
        'A list of counts of each type of content in this version.'),
                                            read_only=True)
    base_version = NestedRelatedField(
        required=False,
        help_text=_(
            'A repository version whose content was used as the initial set of content '
            'for this repository version'),
        queryset=models.RepositoryVersion.objects.all(),
        view_name='versions-detail',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
    )

    class Meta:
        model = models.RepositoryVersion
        fields = ModelSerializer.Meta.fields + (
            '_href', '_content_href', '_added_href', '_removed_href', 'number',
            'content_summary', 'base_version')
Пример #9
0
class RepositoryVersionCreateSerializer(ModelSerializer, NestedHyperlinkedModelSerializer):
    add_content_units = serializers.ListField(
        help_text=_('A list of content units to add to a new repository version'),
        write_only=True
    )
    remove_content_units = serializers.ListField(
        help_text=_('A list of content units to remove from the latest repository version'),
        write_only=True
    )
    base_version = NestedRelatedField(
        required=False,
        help_text=_('A repository version whose content will be used as the initial set of content '
                    'for the new repository version'),
        queryset=models.RepositoryVersion.objects.all(),
        view_name='versions-detail',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
    )

    class Meta:
        model = models.RepositoryVersion
        fields = ['add_content_units', 'remove_content_units', 'base_version']
Пример #10
0
class RepositoryVersionSerializer(ModelSerializer,
                                  NestedHyperlinkedModelSerializer):
    _href = NestedIdentityField(
        view_name='versions-detail',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
    )
    number = serializers.IntegerField(read_only=True)
    base_version = NestedRelatedField(
        required=False,
        help_text=_(
            'A repository version whose content was used as the initial set of content '
            'for this repository version'),
        queryset=models.RepositoryVersion.objects.all(),
        view_name='versions-detail',
        lookup_field='number',
        parent_lookup_kwargs={'repository_pk': 'repository__pk'},
    )
    content_hrefs = serializers.SerializerMethodField(
        help_text=_(
            'A mapping of the types of content in this version, and the HREF to view '
            'them.'),
        read_only=True,
    )
    content_added_hrefs = serializers.SerializerMethodField(
        help_text=_(
            'A mapping of the types of content added in this version, and the HREF to '
            'view them.'),
        read_only=True,
    )
    content_removed_hrefs = serializers.SerializerMethodField(
        help_text=_(
            'A mapping of the types of content removed from this version, and the HREF '
            'to view them.'),
        read_only=True,
    )
    content_summary = serializers.SerializerMethodField(
        help_text=_(
            'A list of counts of each type of content in this version.'),
        read_only=True,
    )
    content_added_summary = serializers.SerializerMethodField(
        help_text=_(
            'A list of counts of each type of content added in this version.'),
        read_only=True,
    )
    content_removed_summary = serializers.SerializerMethodField(
        help_text=_(
            'A list of counts of each type of content removed in this version.'
        ),
        read_only=True,
    )

    def get_content_summary(self, obj):
        """
        The summary of contained content.

        Returns:
            dict: of {<_type>: <count>}
        """
        annotated = obj.content.values('_type').annotate(count=Count('_type'))
        return {c['_type']: c['count'] for c in annotated}

    def get_content_added_summary(self, obj):
        """
        The summary of added content.

        Returns:
            dict: of {<_type>: <count>}
        """
        annotated = obj.added().values('_type').annotate(count=Count('_type'))
        return {c['_type']: c['count'] for c in annotated}

    def get_content_removed_summary(self, obj):
        """
        The summary of removed content.

        Returns:
            dict: of {<_type>: <count>}
        """
        annotated = obj.removed().values('_type').annotate(
            count=Count('_type'))
        return {c['_type']: c['count'] for c in annotated}

    def get_content_hrefs(self, obj):
        """
        Generate URLs for the content types present in the RepositoryVersion.

        For each content type present in the RepositoryVersion, create the URL of the viewset of
        that variety of content along with a query parameter which filters it by presence in this
        RepositoryVersion.

        Args:
            obj (pulpcore.app.models.RepositoryVersion): The RepositoryVersion being serialized.

        Returns:
            dict: {<_type>: <url>}
        """
        content_urls = {}

        for ctype in obj.content.values_list('_type', flat=True).distinct():
            ctype_model = obj.content.filter(
                _type=ctype).first().cast().__class__
            ctype_view = get_view_name_for_model(ctype_model, 'list')
            try:
                ctype_url = reverse(ctype_view)
            except django.urls.exceptions.NoReverseMatch:
                # We've hit a content type for which there is no viewset.
                # There's nothing we can do here, except to skip it.
                continue
            rv_href = "/pulp/api/v3/repositories/{repo}/versions/{version}/".format(
                repo=obj.repository.pk, version=obj.number)
            full_url = "{base}?repository_version={rv_href}".format(
                base=ctype_url, rv_href=rv_href)
            content_urls[ctype] = full_url

        return content_urls

    def get_content_added_hrefs(self, obj):
        """
        Generate URLs for the content types added in the RepositoryVersion.

        For each content type added in the RepositoryVersion, create the URL of the viewset of
        that variety of content along with a query parameter which filters it by addition in this
        RepositoryVersion.

        Args:
            obj (pulpcore.app.models.RepositoryVersion): The RepositoryVersion being serialized.

        Returns:
            dict: {<_type>: <url>}
        """
        content_urls = {}

        for ctype in obj.added().values_list('_type', flat=True).distinct():
            ctype_model = obj.content.filter(
                _type=ctype).first().cast().__class__
            ctype_view = get_view_name_for_model(ctype_model, 'list')
            try:
                ctype_url = reverse(ctype_view)
            except django.urls.exceptions.NoReverseMatch:
                # We've hit a content type for which there is no viewset.
                # There's nothing we can do here, except to skip it.
                continue
            rv_href = "/pulp/api/v3/repositories/{repo}/versions/{version}/".format(
                repo=obj.repository.pk, version=obj.number)
            full_url = "{base}?repository_version_added={rv_href}".format(
                base=ctype_url, rv_href=rv_href)
            content_urls[ctype] = full_url

        return content_urls

    def get_content_removed_hrefs(self, obj):
        """
        Generate URLs for the content types removed in the RepositoryVersion.

        For each content type removed in the RepositoryVersion, create the URL of the viewset of
        that variety of content along with a query parameter which filters it by removal in this
        RepositoryVersion.

        Args:
            obj (pulpcore.app.models.RepositoryVersion): The RepositoryVersion being serialized.

        Returns:
            dict: {<_type>: <url>}
        """
        content_urls = {}

        for ctype in obj.removed().values_list('_type', flat=True).distinct():
            ctype_model = obj.content.filter(
                _type=ctype).first().cast().__class__
            ctype_view = get_view_name_for_model(ctype_model, 'list')
            try:
                ctype_url = reverse(ctype_view)
            except django.urls.exceptions.NoReverseMatch:
                # We've hit a content type for which there is no viewset.
                # There's nothing we can do here, except to skip it.
                continue
            rv_href = "/pulp/api/v3/repositories/{repo}/versions/{version}/".format(
                repo=obj.repository.pk, version=obj.number)
            full_url = "{base}?repository_version_removed={rv_href}".format(
                base=ctype_url, rv_href=rv_href)
            content_urls[ctype] = full_url

        return content_urls

    class Meta:
        model = models.RepositoryVersion
        fields = ModelSerializer.Meta.fields + (
            '_href',
            'number',
            'base_version',
            'content_hrefs',
            'content_added_hrefs',
            'content_removed_hrefs',
            'content_summary',
            'content_added_summary',
            'content_removed_summary',
        )