Exemple #1
0
class PythonDistributionSerializer(core_serializers.DistributionSerializer):
    """
    Serializer for Pulp distributions for the Python type.
    """

    publication = core_serializers.DetailRelatedField(
        required=False,
        help_text=_("Publication to be served"),
        view_name_pattern=r"publications(-.*/.*)?-detail",
        queryset=core_models.Publication.objects.exclude(complete=False),
        allow_null=True,
    )
    base_url = serializers.SerializerMethodField(read_only=True)
    allow_uploads = serializers.BooleanField(
        default=True,
        help_text=_("Allow packages to be uploaded to this index."))
    remote = core_serializers.DetailRelatedField(
        required=False,
        help_text=
        _('Remote that can be used to fetch content when using pull-through caching.'
          ),
        view_name_pattern=r"remotes(-.*/.*)?-detail",
        queryset=core_models.Remote.objects.all(),
        allow_null=True)

    def get_base_url(self, obj):
        """Gets the base url."""
        return f"{settings.PYPI_API_HOSTNAME}/pypi/{obj.base_path}/"

    class Meta:
        fields = core_serializers.DistributionSerializer.Meta.fields + (
            'publication', "allow_uploads", "remote")
        model = python_models.PythonDistribution
Exemple #2
0
class ManifestSerializer(platform.ContentSerializer):
    """
    Serializer for Manifests.
    """

    digest = serializers.CharField(help_text="sha256 of the Manifest file")
    schema_version = serializers.IntegerField(
        help_text="Docker schema version")
    media_type = serializers.CharField(
        help_text="Docker media type of the file")
    blobs = platform.DetailRelatedField(
        many=True,
        help_text="Blobs that are referenced by this Manifest",
        view_name='docker-blobs-detail',
        queryset=models.ManifestBlob.objects.all())
    config_blob = platform.DetailRelatedField(
        many=False,
        help_text="Blob that contains configuration for this Manifest",
        view_name='docker-blobs-detail',
        queryset=models.ManifestBlob.objects.all())
    _artifact = MinimalArtifactSerializer(
        many=False, help_text="File related to this content")

    class Meta:
        fields = tuple(
            set(platform.ContentSerializer.Meta.fields) -
            {'_artifacts'}) + ('digest', 'schema_version', 'media_type',
                               'blobs', 'config_blob', '_artifact')
        model = models.ImageManifest
Exemple #3
0
class MavenDistributionSerializer(platform.BaseDistributionSerializer):
    """
    Serializer for Maven Distributions.
    """

    remote = platform.DetailRelatedField(
        required=False,
        help_text=
        _("Remote that can be used to fetch content when using pull-through caching."
          ),
        queryset=models.MavenRemote.objects.all(),
        allow_null=True,
    )

    class Meta:
        fields = platform.BaseDistributionSerializer.Meta.fields + ("remote", )
        model = models.MavenDistribution
Exemple #4
0
class PythonPublicationSerializer(core_serializers.PublicationSerializer):
    """
    A Serializer for PythonPublication.
    """

    distributions = core_serializers.DetailRelatedField(
        help_text=_('This publication is currently being hosted as configured by these '
                    'distributions.'),
        source="python_pythondistribution",
        view_name="filedistributions-detail",
        many=True,
        read_only=True,
    )

    class Meta:
        fields = core_serializers.PublicationSerializer.Meta.fields + ('distributions',)
        model = python_models.PythonPublication
Exemple #5
0
class PythonDistributionSerializer(core_serializers.DistributionSerializer):
    """
    Serializer for Pulp distributions for the Python type.

    """

    publication = core_serializers.DetailRelatedField(
        required=False,
        help_text=_("Publication to be served"),
        view_name_pattern=r"publications(-.*/.*)?-detail",
        queryset=core_models.Publication.objects.exclude(complete=False),
        allow_null=True,
    )

    class Meta:
        fields = core_serializers.DistributionSerializer.Meta.fields + (
            'publication', )
        model = python_models.PythonDistribution
Exemple #6
0
class PythonDistributionSerializer(core_serializers.DistributionSerializer):
    """
    Serializer for Pulp distributions for the Python type.
    """

    publication = core_serializers.DetailRelatedField(
        required=False,
        help_text=_("Publication to be served"),
        view_name_pattern=r"publications(-.*/.*)?-detail",
        queryset=core_models.Publication.objects.exclude(complete=False),
        allow_null=True,
    )
    base_url = serializers.SerializerMethodField(read_only=True)
    allow_uploads = serializers.BooleanField(
        default=True,
        help_text=_("Allow packages to be uploaded to this index."))

    def get_base_url(self, obj):
        """Gets the base url."""
        return f"{settings.PYPI_API_HOSTNAME}/pypi/{obj.base_path}/"

    def validate(self, data):
        """
        Ensure publication and repository are not set at the same time.

        This is needed here till https://pulp.plan.io/issues/8761 is resolved.
        """
        data = super().validate(data)
        repository_provided = data.get("repository", None)
        publication_provided = data.get("publication", None)

        if repository_provided and publication_provided:
            raise serializers.ValidationError(
                _("Only one of the attributes 'repository' and 'publication' "
                  "may be used simultaneously."))
        if repository_provided or publication_provided:
            data["repository"] = repository_provided
            data["publication"] = publication_provided
        return data

    class Meta:
        fields = core_serializers.DistributionSerializer.Meta.fields + (
            'publication', "allow_uploads")
        model = python_models.PythonDistribution
Exemple #7
0
class ManifestTagSerializer(platform.ContentSerializer):
    """
    Serializer for ManifestTags.
    """

    name = serializers.CharField(help_text="Tag name")
    manifest = platform.DetailRelatedField(
        many=False,
        help_text="Manifest that is tagged",
        view_name='docker-manifests-detail',
        queryset=models.ImageManifest.objects.all())
    _artifact = MinimalArtifactSerializer(
        many=False, help_text="File related to this content")

    class Meta:
        fields = tuple(
            set(platform.ContentSerializer.Meta.fields) -
            {'_artifacts'}) + ('name', 'manifest', '_artifact')
        model = models.ManifestTag
Exemple #8
0
class DockerDistributionSerializer(platform.ModelSerializer):
    """
    A serializer for DockerDistribution.
    """

    _href = platform.IdentityField(view_name='docker-distributions-detail')
    name = serializers.CharField(
        help_text=_('A unique distribution name. Ex, `rawhide` and `stable`.'),
        validators=[
            validators.MaxLengthValidator(
                models.DockerDistribution._meta.get_field('name').max_length,
                message=_(
                    'Distribution name length must be less than {} characters'
                ).format(
                    models.DockerDistribution._meta.get_field(
                        'name').max_length)),
            UniqueValidator(queryset=models.DockerDistribution.objects.all())
        ])
    base_path = serializers.CharField(
        help_text=
        _('The base (relative) path component of the published url. Avoid paths that \
                    overlap with other distribution base paths (e.g. "foo" and "foo/bar")'
          ),
        validators=[
            validators.MaxLengthValidator(
                models.DockerDistribution._meta.get_field(
                    'base_path').max_length,
                message=
                _('Distribution base_path length must be less than {} characters'
                  ).format(
                      models.DockerDistribution._meta.get_field(
                          'base_path').max_length)),
            UniqueValidator(queryset=models.DockerDistribution.objects.all()),
        ])
    publisher = platform.DetailRelatedField(
        required=False,
        help_text=_(
            'Publications created by this publisher and repository are automatically'
            'served as defined by this distribution'),
        queryset=models.DockerPublisher.objects.all(),
        allow_null=True)
    publication = platform.RelatedField(
        required=False,
        help_text=_(
            'The publication being served as defined by this distribution'),
        queryset=Publication.objects.exclude(complete=False),
        view_name='publications-detail',
        allow_null=True)
    repository = platform.RelatedField(
        required=False,
        help_text=_(
            'Publications created by this repository and publisher are automatically'
            'served as defined by this distribution'),
        queryset=Repository.objects.all(),
        view_name='repositories-detail',
        allow_null=True)
    registry_path = RegistryPathField(
        source='base_path',
        read_only=True,
        help_text=_(
            'The Registry hostame:port/name/ to use with docker pull command defined by '
            'this distribution.'))

    class Meta:
        model = models.DockerDistribution
        fields = platform.ModelSerializer.Meta.fields + (
            'name',
            'base_path',
            'publisher',
            'publication',
            'registry_path',
            'repository',
            'content_guard',
        )

    def _validate_path_overlap(self, path):
        # look for any base paths nested in path
        search = path.split("/")[0]
        q = Q(base_path=search)
        for subdir in path.split("/")[1:]:
            search = "/".join((search, subdir))
            q |= Q(base_path=search)

        # look for any base paths that nest path
        q |= Q(base_path__startswith='{}/'.format(path))
        qs = models.DockerDistribution.objects.filter(q)

        if self.instance is not None:
            qs = qs.exclude(pk=self.instance.pk)

        match = qs.first()
        if match:
            raise serializers.ValidationError(
                detail=_("Overlaps with existing distribution '"
                         "{}'").format(match.name))

        return path

    def validate_base_path(self, path):
        """
        Validate that path is valid.

        Args:
            path (str): the path at which the registry will be served at
        """
        self._validate_relative_path(path)
        return self._validate_path_overlap(path)

    def validate(self, data):
        """
        Validates that the data dict has valid DockerDistribution info.

        Args:
            data (dict): dict representing a DockerDistribution
        """
        super().validate(data)

        if 'publisher' in data:
            publisher = data['publisher']
        elif self.instance:
            publisher = self.instance.publisher
        else:
            publisher = None

        if 'repository' in data:
            repository = data['repository']
        elif self.instance:
            repository = self.instance.repository
        else:
            repository = None

        if publisher and not repository:
            raise serializers.ValidationError({
                'repository':
                _("Repository must be set if "
                  "publisher is set.")
            })
        if repository and not publisher:
            raise serializers.ValidationError({
                'publisher':
                _("Publisher must be set if "
                  "repository is set.")
            })

        return data