示例#1
0
class RepositorySerializer(ModelSerializer):
    pulp_href = DetailIdentityField(
        view_name_pattern=r"repositories(-.*/.*)-detail", )
    versions_href = RepositoryVersionsIdentityFromRepositoryField()
    latest_version_href = LatestVersionField()
    name = serializers.CharField(
        help_text=_("A unique name for this repository."),
        validators=[UniqueValidator(queryset=models.Repository.objects.all())],
    )
    description = serializers.CharField(
        help_text=_("An optional description."),
        required=False,
        allow_null=True)

    class Meta:
        model = models.Repository
        fields = ModelSerializer.Meta.fields + (
            "versions_href",
            "latest_version_href",
            "name",
            "description",
        )
示例#2
0
class RepositorySerializer(ModelSerializer):
    pulp_href = DetailIdentityField(
        view_name_pattern=r"repositories(-.*/.*)-detail")
    pulp_labels = LabelsField(required=False)
    versions_href = RepositoryVersionsIdentityFromRepositoryField()
    latest_version_href = LatestVersionField()
    name = serializers.CharField(
        help_text=_("A unique name for this repository."),
        validators=[UniqueValidator(queryset=models.Repository.objects.all())],
    )
    description = serializers.CharField(
        help_text=_("An optional description."),
        required=False,
        allow_null=True)
    remote = DetailRelatedField(
        view_name_pattern=r"remotes(-.*/.*)-detail",
        queryset=models.Remote.objects.all(),
        required=False,
        allow_null=True,
    )

    def validate_remote(self, value):
        if value and type(value) not in self.Meta.model.REMOTE_TYPES:
            raise serializers.ValidationError(
                detail=_("Type for Remote '{}' does not match Repository."
                         ).format(value.name))

        return value

    class Meta:
        model = models.Repository
        fields = ModelSerializer.Meta.fields + (
            "versions_href",
            "pulp_labels",
            "latest_version_href",
            "name",
            "description",
            "remote",
        )
示例#3
0
class ExporterSerializer(MasterModelSerializer):
    _href = DetailIdentityField()
    name = serializers.CharField(
        help_text=_('The exporter unique name.'),
        validators=[UniqueValidator(queryset=models.Exporter.objects.all())]
    )
    last_updated = serializers.DateTimeField(
        help_text=_('Timestamp of the last update.'),
        read_only=True
    )
    last_export = serializers.DateTimeField(
        help_text=_('Timestamp of the last export.'),
        read_only=True
    )

    class Meta:
        abstract = True
        model = models.Exporter
        fields = MasterModelSerializer.Meta.fields + (
            'name',
            'last_updated',
            'last_export',
        )
示例#4
0
class RemoteSerializer(MasterModelSerializer):
    """
    Every remote defined by a plugin should have a Remote serializer that inherits from this
    class. Please import from `pulpcore.plugin.serializers` rather than from this module directly.
    """
    _href = DetailIdentityField()
    name = serializers.CharField(
        help_text=_('A unique name for this remote.'),
        validators=[UniqueValidator(queryset=models.Remote.objects.all())],
    )
    url = serializers.CharField(
        help_text='The URL of an external content source.', )
    validate = serializers.BooleanField(
        help_text='If True, the plugin will validate imported artifacts.',
        required=False,
    )
    ssl_ca_certificate = serializers.FileField(
        help_text='A PEM encoded CA certificate used to validate the server '
        'certificate presented by the remote server.',
        write_only=True,
        required=False,
    )
    ssl_client_certificate = serializers.FileField(
        help_text='A PEM encoded client certificate used for authentication.',
        write_only=True,
        required=False,
    )
    ssl_client_key = serializers.FileField(
        help_text='A PEM encoded private key used for authentication.',
        write_only=True,
        required=False,
    )
    ssl_validation = serializers.BooleanField(
        help_text='If True, SSL peer validation must be performed.',
        required=False,
    )
    proxy_url = serializers.CharField(
        help_text='The proxy URL. Format: scheme://user:password@host:port',
        required=False,
        allow_blank=True,
    )
    username = serializers.CharField(
        help_text='The username to be used for authentication when syncing.',
        write_only=True,
        required=False,
        allow_blank=True,
    )
    password = serializers.CharField(
        help_text='The password to be used for authentication when syncing.',
        write_only=True,
        required=False,
        allow_blank=True,
    )
    _last_updated = serializers.DateTimeField(
        help_text='Timestamp of the most recent update of the remote.',
        read_only=True)
    download_concurrency = serializers.IntegerField(
        help_text='Total number of simultaneous connections.',
        required=False,
        min_value=1)
    policy = serializers.ChoiceField(
        help_text=
        "The policy to use when downloading content. The possible values include: "
        "'immediate', 'on_demand', and 'cache_only'. 'immediate' is the default.",
        choices=models.Remote.POLICY_CHOICES,
        default=models.Remote.IMMEDIATE)

    class Meta:
        abstract = True
        model = models.Remote
        fields = MasterModelSerializer.Meta.fields + (
            'name', 'url', 'validate', 'ssl_ca_certificate',
            'ssl_client_certificate', 'ssl_client_key', 'ssl_validation',
            'proxy_url', 'username', 'password', '_last_updated',
            'download_concurrency', 'policy')
示例#5
0
class RemoteSerializer(ModelSerializer):
    """
    Every remote defined by a plugin should have a Remote serializer that inherits from this
    class. Please import from `pulpcore.plugin.serializers` rather than from this module directly.
    """
    pulp_href = DetailIdentityField()
    name = serializers.CharField(
        help_text=_('A unique name for this remote.'),
        validators=[UniqueValidator(queryset=models.Remote.objects.all())],
    )
    url = serializers.CharField(
        help_text='The URL of an external content source.', )
    ssl_ca_certificate = SecretCharField(
        help_text=
        'A string containing the PEM encoded CA certificate used to validate the server '
        'certificate presented by the remote server. All new line characters must be '
        'escaped. Returns SHA256 sum on GET.',
        write_only=False,
        required=False,
        allow_null=True,
    )
    ssl_client_certificate = SecretCharField(
        help_text=
        'A string containing the PEM encoded client certificate used for authentication. '
        'All new line characters must be escaped. Returns SHA256 sum on GET.',
        write_only=False,
        required=False,
        allow_null=True,
    )
    ssl_client_key = SecretCharField(
        help_text=
        'A PEM encoded private key used for authentication. Returns SHA256 sum on GET.',
        write_only=False,
        required=False,
        allow_null=True,
    )
    ssl_validation = serializers.BooleanField(
        help_text='If True, SSL peer validation must be performed.',
        required=False,
    )
    proxy_url = serializers.CharField(
        help_text='The proxy URL. Format: scheme://user:password@host:port',
        required=False,
        allow_null=True,
    )
    username = serializers.CharField(
        help_text='The username to be used for authentication when syncing.',
        write_only=True,
        required=False,
        allow_null=True,
    )
    password = serializers.CharField(
        help_text='The password to be used for authentication when syncing.',
        write_only=True,
        required=False,
        allow_null=True,
    )
    pulp_last_updated = serializers.DateTimeField(
        help_text='Timestamp of the most recent update of the remote.',
        read_only=True)
    download_concurrency = serializers.IntegerField(
        help_text='Total number of simultaneous connections.',
        required=False,
        min_value=1)
    policy = serializers.ChoiceField(
        help_text="The policy to use when downloading content.",
        choices=((models.Remote.IMMEDIATE,
                  'When syncing, download all metadata and content now.')),
        default=models.Remote.IMMEDIATE)

    class Meta:
        abstract = True
        model = models.Remote
        fields = ModelSerializer.Meta.fields + (
            'name', 'url', 'ssl_ca_certificate', 'ssl_client_certificate',
            'ssl_client_key', 'ssl_validation', 'proxy_url', 'username',
            'password', 'pulp_last_updated', 'download_concurrency', 'policy')
示例#6
0
class RemoteSerializer(MasterModelSerializer):
    """
    Every remote defined by a plugin should have an Remote serializer that inherits from this
    class. Please import from `pulpcore.plugin.serializers` rather than from this module directly.
    """
    _href = DetailIdentityField()
    name = serializers.CharField(
        help_text=_('A unique name for this remote.'),
        validators=[UniqueValidator(queryset=models.Remote.objects.all())])
    url = serializers.CharField(
        help_text='The URL of an external content source.', )
    validate = serializers.BooleanField(
        help_text='If True, the plugin will validate imported artifacts.',
        required=False,
    )
    ssl_ca_certificate = serializers.FileField(
        help_text='A PEM encoded CA certificate used to validate the server '
        'certificate presented by the remote server.',
        write_only=True,
        required=False,
    )
    ssl_client_certificate = serializers.FileField(
        help_text='A PEM encoded client certificate used for authentication.',
        write_only=True,
        required=False,
    )
    ssl_client_key = serializers.FileField(
        help_text='A PEM encoded private key used for authentication.',
        write_only=True,
        required=False,
    )
    ssl_validation = serializers.BooleanField(
        help_text='If True, SSL peer validation must be performed.',
        required=False,
    )
    proxy_url = serializers.CharField(
        help_text='The proxy URL. Format: scheme://user:password@host:port',
        required=False,
    )
    username = serializers.CharField(
        help_text='The username to be used for authentication when syncing.',
        write_only=True,
        required=False,
    )
    password = serializers.CharField(
        help_text='The password to be used for authentication when syncing.',
        write_only=True,
        required=False,
    )
    last_synced = serializers.DateTimeField(
        help_text='Timestamp of the most recent successful sync.',
        read_only=True)
    last_updated = serializers.DateTimeField(
        help_text='Timestamp of the most recent update of the remote.',
        read_only=True)

    class Meta:
        abstract = True
        model = models.Remote
        fields = MasterModelSerializer.Meta.fields + (
            'name',
            'url',
            'validate',
            'ssl_ca_certificate',
            'ssl_client_certificate',
            'ssl_client_key',
            'ssl_validation',
            'proxy_url',
            'username',
            'password',
            'last_synced',
            'last_updated',
        )
示例#7
0
class DistributionSerializer(ModelSerializer):
    """
    The Serializer for the Distribution model.

    The serializer deliberately omits the the `publication` and `repository_version` field due to
    plugins typically requiring one or the other but not both.

    To include the ``publication`` field, it is recommended plugins define the field::

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

    To include the ``repository_version`` field, it is recommended plugins define the field::

      repository_version = RepositoryVersionRelatedField(
          required=False, help_text=_("RepositoryVersion to be served"), allow_null=True
      )

    Additionally, the serializer omits the ``remote`` field, which is used for pull-through caching
    feature and only by plugins which use publications. Plugins implementing a pull-through caching
    should define the field in their derived serializer class like this::

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

    """

    pulp_href = DetailIdentityField(
        view_name_pattern=r"distributions(-.*/.*)-detail")
    pulp_labels = LabelsField(required=False)

    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=[
            UniqueValidator(queryset=models.Distribution.objects.all())
        ],
    )
    base_url = BaseURLField(
        source="base_path",
        read_only=True,
        help_text=
        _("The URL for accessing the publication as defined by this distribution."
          ),
    )
    content_guard = DetailRelatedField(
        required=False,
        help_text=_("An optional content-guard."),
        view_name_pattern=r"contentguards(-.*/.*)?-detail",
        queryset=models.ContentGuard.objects.all(),
        allow_null=True,
    )
    name = serializers.CharField(
        help_text=_("A unique name. Ex, `rawhide` and `stable`."),
        validators=[
            UniqueValidator(queryset=models.Distribution.objects.all()),
        ],
    )
    repository = DetailRelatedField(
        required=False,
        help_text=_(
            "The latest RepositoryVersion for this Repository will be served."
        ),
        view_name_pattern=r"repositories(-.*/.*)?-detail",
        queryset=models.Repository.objects.all(),
        allow_null=True,
    )

    class Meta:
        abstract = True
        model = models.Distribution
        fields = ModelSerializer.Meta.fields + (
            "base_path",
            "base_url",
            "content_guard",
            "pulp_labels",
            "name",
            "repository",
        )

    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.Distribution.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):
        self._validate_relative_path(path)
        return self._validate_path_overlap(path)

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

        repository_provided = data.get(
            "repository", (self.instance and self.instance.repository) or None)
        repository_version_provided = data.get(
            "repository_version",
            (self.instance and self.instance.repository_version) or None)
        publication_provided = data.get(
            "publication", (self.instance and self.instance.publication)
            or None)

        if publication_provided and repository_version_provided:
            raise serializers.ValidationError(
                _("Only one of the attributes 'publication' and 'repository_version' "
                  "may be used simultaneously."))
        elif repository_provided and repository_version_provided:
            raise serializers.ValidationError(
                _("Only one of the attributes 'repository' and 'repository_version' "
                  "may be used simultaneously."))

        elif repository_provided and publication_provided:
            raise serializers.ValidationError(
                _("Only one of the attributes 'repository' and 'publication' "
                  "may be used simultaneously."))
        return data
示例#8
0
class RemoteSerializer(ModelSerializer):
    """
    Every remote defined by a plugin should have a Remote serializer that inherits from this
    class. Please import from `pulpcore.plugin.serializers` rather than from this module directly.
    """
    pulp_href = DetailIdentityField()
    name = serializers.CharField(
        help_text=_('A unique name for this remote.'),
        validators=[UniqueValidator(queryset=models.Remote.objects.all())],
    )
    url = serializers.CharField(
        help_text='The URL of an external content source.',
    )
    ca_cert = SecretCharField(
        help_text='A string containing the PEM encoded CA certificate used to validate the server '
                  'certificate presented by the remote server. All new line characters must be '
                  'escaped. Returns SHA256 checksum of the certificate file on GET.',
        write_only=False,
        required=False,
        allow_null=True,
    )
    client_cert = SecretCharField(
        help_text='A string containing the PEM encoded client certificate used for authentication. '
                  'All new line characters must be escaped. Returns SHA256 checksum of the '
                  'certificate file on GET.',
        write_only=False,
        required=False,
        allow_null=True,
    )
    client_key = SecretCharField(
        help_text='A PEM encoded private key used for authentication. Returns SHA256 checksum of '
                  'the certificate file on GET.',
        write_only=False,
        required=False,
        allow_null=True,
    )
    tls_validation = serializers.BooleanField(
        help_text='If True, TLS peer validation must be performed.',
        required=False,
    )
    proxy_url = serializers.CharField(
        help_text='The proxy URL. Format: scheme://user:password@host:port',
        required=False,
        allow_null=True,
    )
    username = serializers.CharField(
        help_text='The username to be used for authentication when syncing.',
        write_only=True,
        required=False,
        allow_null=True,
    )
    password = serializers.CharField(
        help_text='The password to be used for authentication when syncing.',
        write_only=True,
        required=False,
        allow_null=True,
    )
    pulp_last_updated = serializers.DateTimeField(
        help_text='Timestamp of the most recent update of the remote.',
        read_only=True
    )
    download_concurrency = serializers.IntegerField(
        help_text='Total number of simultaneous connections.',
        required=False,
        min_value=1
    )
    policy = serializers.ChoiceField(
        help_text="The policy to use when downloading content.",
        choices=(
            (models.Remote.IMMEDIATE, 'When syncing, download all metadata and content now.')
        ),
        default=models.Remote.IMMEDIATE
    )

    def validate_url(self, value):
        """
        Check if the 'url' is a ``file://`` path, and if so, ensure it's an ALLOWED_IMPORT_PATH.

        The ALLOWED_IMPORT_PATH is specified as a Pulp setting.

        Args:
            value: The user-provided value for 'url' to be validated.

        Raises:
            ValidationError: When the url starts with `file://`, but is not a subfolder of a path in
                the ALLOWED_IMPORT_PATH setting.

        Returns:
            The validated value.
        """
        if not value.lower().startswith('file://'):
            return value

        user_path = value[7:]

        for allowed_path in settings.ALLOWED_IMPORT_PATHS:
            user_provided_realpath = os.path.realpath(user_path)
            if user_provided_realpath.startswith(allowed_path):
                return value
        raise serializers.ValidationError(_("url '{}' is not an allowed import path").format(value))

    class Meta:
        abstract = True
        model = models.Remote
        fields = ModelSerializer.Meta.fields + (
            'name', 'url', 'ca_cert', 'client_cert', 'client_key',
            'tls_validation', 'proxy_url', 'username', 'password', 'pulp_last_updated',
            'download_concurrency', 'policy'
        )
示例#9
0
class RemoteSerializer(ModelSerializer):
    """
    Every remote defined by a plugin should have a Remote serializer that inherits from this
    class. Please import from `pulpcore.plugin.serializers` rather than from this module directly.
    """

    pulp_href = DetailIdentityField(view_name_pattern=r"remotes(-.*/.*)-detail")
    pulp_labels = LabelsField(required=False)
    name = serializers.CharField(
        help_text=_("A unique name for this remote."),
        validators=[UniqueValidator(queryset=models.Remote.objects.all())],
    )
    url = serializers.CharField(help_text="The URL of an external content source.")
    ca_cert = serializers.CharField(
        help_text="A PEM encoded CA certificate used to validate the server "
        "certificate presented by the remote server.",
        required=False,
        allow_null=True,
    )
    client_cert = serializers.CharField(
        help_text="A PEM encoded client certificate used for authentication.",
        required=False,
        allow_null=True,
    )
    client_key = serializers.CharField(
        help_text="A PEM encoded private key used for authentication.",
        required=False,
        allow_null=True,
    )
    tls_validation = serializers.BooleanField(
        help_text="If True, TLS peer validation must be performed.", required=False
    )
    proxy_url = serializers.CharField(
        help_text="The proxy URL. Format: scheme://user:password@host:port",
        required=False,
        allow_null=True,
    )
    username = serializers.CharField(
        help_text="The username to be used for authentication when syncing.",
        required=False,
        allow_null=True,
    )
    password = serializers.CharField(
        help_text="The password to be used for authentication when syncing.",
        required=False,
        allow_null=True,
    )
    pulp_last_updated = serializers.DateTimeField(
        help_text="Timestamp of the most recent update of the remote.", read_only=True
    )
    download_concurrency = serializers.IntegerField(
        help_text="Total number of simultaneous connections.", required=False, min_value=1
    )
    policy = serializers.ChoiceField(
        help_text="The policy to use when downloading content.",
        choices=((models.Remote.IMMEDIATE, "When syncing, download all metadata and content now.")),
        default=models.Remote.IMMEDIATE,
    )

    total_timeout = serializers.FloatField(
        allow_null=True,
        required=False,
        help_text="aiohttp.ClientTimeout.total (q.v.) for download-connections.",
        min_value=0.0,
    )
    connect_timeout = serializers.FloatField(
        allow_null=True,
        required=False,
        help_text="aiohttp.ClientTimeout.connect (q.v.) for download-connections.",
        min_value=0.0,
    )
    sock_connect_timeout = serializers.FloatField(
        allow_null=True,
        required=False,
        help_text="aiohttp.ClientTimeout.sock_connect (q.v.) for download-connections.",
        min_value=0.0,
    )
    sock_read_timeout = serializers.FloatField(
        allow_null=True,
        required=False,
        help_text="aiohttp.ClientTimeout.sock_read (q.v.) for download-connections.",
        min_value=0.0,
    )
    headers = serializers.ListField(
        child=serializers.DictField(),
        help_text=_("Headers for aiohttp.Clientsession"),
    )
    rate_limit = serializers.IntegerField(
        help_text=_("Limits total download rate in requests per second"),
        allow_null=True,
        required=False,
    )

    def validate_url(self, value):
        """
        Check if the 'url' is a ``file://`` path, and if so, ensure it's an ALLOWED_IMPORT_PATH.

        The ALLOWED_IMPORT_PATH is specified as a Pulp setting.

        Args:
            value: The user-provided value for 'url' to be validated.

        Raises:
            ValidationError: When the url starts with `file://`, but is not a subfolder of a path in
                the ALLOWED_IMPORT_PATH setting.

        Returns:
            The validated value.
        """
        if not value.lower().startswith("file://"):
            return value

        user_path = value[7:]

        for allowed_path in settings.ALLOWED_IMPORT_PATHS:
            user_provided_realpath = os.path.realpath(user_path)
            if user_provided_realpath.startswith(allowed_path):
                return value
        raise serializers.ValidationError(_("url '{}' is not an allowed import path").format(value))

    class Meta:
        abstract = True
        model = models.Remote
        fields = ModelSerializer.Meta.fields + (
            "name",
            "url",
            "ca_cert",
            "client_cert",
            "client_key",
            "tls_validation",
            "proxy_url",
            "username",
            "password",
            "pulp_labels",
            "pulp_last_updated",
            "download_concurrency",
            "policy",
            "total_timeout",
            "connect_timeout",
            "sock_connect_timeout",
            "sock_read_timeout",
            "rate_limit",
        )
示例#10
0
class DistributionSerializer(ModelSerializer, BasePathOverlapMixin):
    """
    The Serializer for the Distribution model.

    The serializer deliberately omits the the `publication` and `repository_version` field due to
    plugins typically requiring one or the other but not both.

    To include the ``publication`` field, it is recommended plugins define the field::

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

    To include the ``repository_version`` field, it is recommended plugins define the field::

      repository_version = RepositoryVersionRelatedField(
          required=False, help_text=_("RepositoryVersion to be served"), allow_null=True
      )

    Additionally, the serializer omits the ``remote`` field, which is used for pull-through caching
    feature and only by plugins which use publications. Plugins implementing a pull-through caching
    should define the field in their derived serializer class like this::

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

    """

    pulp_href = DetailIdentityField(
        view_name_pattern=r"distributions(-.*/.*)-detail")
    pulp_labels = LabelsField(required=False)

    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")'
    ), )
    base_url = BaseURLField(
        source="base_path",
        read_only=True,
        help_text=
        _("The URL for accessing the publication as defined by this distribution."
          ),
    )
    content_guard = DetailRelatedField(
        required=False,
        help_text=_("An optional content-guard."),
        view_name_pattern=r"contentguards(-.*/.*)?-detail",
        queryset=models.ContentGuard.objects.all(),
        allow_null=True,
    )
    name = serializers.CharField(
        help_text=_("A unique name. Ex, `rawhide` and `stable`."),
        validators=[
            UniqueValidator(queryset=models.BaseDistribution.objects.all()),
            UniqueValidator(queryset=models.Distribution.objects.all()),
        ],
    )
    repository = DetailRelatedField(
        required=False,
        help_text=_(
            "The latest RepositoryVersion for this Repository will be served."
        ),
        view_name_pattern=r"repositories(-.*/.*)?-detail",
        queryset=models.Repository.objects.all(),
        allow_null=True,
    )

    class Meta:
        abstract = True
        model = models.BaseDistribution
        fields = ModelSerializer.Meta.fields + (
            "base_path",
            "base_url",
            "content_guard",
            "pulp_labels",
            "name",
            "repository",
        )

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

        publication_in_data = "publication" in data
        repository_version_in_data = "repository_version" in data
        publication_in_instance = self.instance.publication if self.instance else None
        repository_version_in_instance = self.instance.repository_version if self.instance else None

        if publication_in_data and repository_version_in_data:
            error = True
        elif publication_in_data and repository_version_in_instance:
            error = True
        elif publication_in_instance and repository_version_in_data:
            error = True
        else:
            error = False

        if error:
            msg = _(
                "Only one of the attributes 'publication' and 'repository_version' may be used "
                "simultaneously.")
            raise serializers.ValidationError(msg)

        return data
示例#11
0
class BaseDistributionSerializer(ModelSerializer, BasePathOverlapMixin):
    """
    The Serializer for the BaseDistribution model.

    The serializer deliberately omits the "remote" field, which is used for
    pull-through caching only. Plugins implementing pull-through caching will
    have to add the field in their derived serializer class like this::

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

    """

    pulp_href = DetailIdentityField(
        view_name_pattern=r"distributions(-.*/.*)-detail")
    pulp_labels = LabelsField(required=False)
    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=[
            UniqueValidator(queryset=models.BaseDistribution.objects.all())
        ],
    )
    base_url = BaseURLField(
        source="base_path",
        read_only=True,
        help_text=
        _("The URL for accessing the publication as defined by this distribution."
          ),
    )
    content_guard = DetailRelatedField(
        required=False,
        help_text=_("An optional content-guard."),
        view_name_pattern=r"contentguards(-.*/.*)?-detail",
        queryset=models.ContentGuard.objects.all(),
        allow_null=True,
    )
    name = serializers.CharField(
        help_text=_("A unique name. Ex, `rawhide` and `stable`."),
        validators=[
            UniqueValidator(queryset=models.BaseDistribution.objects.all()),
            UniqueValidator(queryset=models.Distribution.objects.all()),
        ],
    )

    def __init__(self, *args, **kwargs):
        """Initialize a BaseDistributionSerializer and emit deprecation warnings"""
        deprecation_logger.warn(
            _("BaseDistributionSerializer is deprecated and could be removed as early as "
              "pulpcore==3.13; use pulpcore.plugin.serializers.DistributionSerializer instead."
              ))
        return super().__init__(*args, **kwargs)

    class Meta:
        abstract = True
        model = models.BaseDistribution
        fields = ModelSerializer.Meta.fields + (
            "base_path",
            "base_url",
            "content_guard",
            "pulp_labels",
            "name",
        )
示例#12
0
class BaseDistributionSerializer(ModelSerializer):
    """
    The Serializer for the BaseDistribution model.

    The serializer deliberately omits the "remote" field, which is used for
    pull-through caching only. Plugins implementing pull-through caching will
    have to add the field in their derived serializer class like this::

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

    """

    pulp_href = DetailIdentityField(
        view_name_pattern=r"distributions(-.*/.*)-detail")
    pulp_labels = LabelsField(required=False)
    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=[
            UniqueValidator(queryset=models.BaseDistribution.objects.all())
        ],
    )
    base_url = BaseURLField(
        source="base_path",
        read_only=True,
        help_text=
        _("The URL for accessing the publication as defined by this distribution."
          ),
    )
    content_guard = DetailRelatedField(
        required=False,
        help_text=_("An optional content-guard."),
        view_name_pattern=r"contentguards(-.*/.*)?-detail",
        queryset=models.ContentGuard.objects.all(),
        allow_null=True,
    )
    name = serializers.CharField(
        help_text=_("A unique name. Ex, `rawhide` and `stable`."),
        validators=[
            UniqueValidator(queryset=models.BaseDistribution.objects.all())
        ],
    )

    class Meta:
        abstract = True
        model = models.BaseDistribution
        fields = ModelSerializer.Meta.fields + (
            "base_path",
            "base_url",
            "content_guard",
            "pulp_labels",
            "name",
        )

    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.BaseDistribution.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):
        self._validate_relative_path(path)
        return self._validate_path_overlap(path)