def validate(self, data):
        """Validates that all the fields make sense."""
        data = super().validate(data)

        if "containerfile" in data:
            if "containerfile_artifact" in data:
                raise serializers.ValidationError(
                    _("Only one of 'containerfile' and 'containerfile_artifact' may be specified.")
                )
            data["containerfile_artifact"] = Artifact.init_and_validate(data.pop("containerfile"))
        elif "containerfile_artifact" not in data:
            raise serializers.ValidationError(_("'containerfile' or 'containerfile_artifact' must "
                                                "be specified."))
        artifacts = {}
        if 'artifacts' in data:
            for url, relative_path in data['artifacts'].items():
                if os.path.isabs(relative_path):
                    raise serializers.ValidationError(_("Relative path cannot start with '/'. "
                                                        "{0}").format(relative_path))
                artifactfield = RelatedField(view_name='artifacts-detail',
                                             queryset=Artifact.objects.all(),
                                             source='*', initial=url)
                try:
                    artifact = artifactfield.run_validation(data=url)
                    artifacts[artifact.pk] = relative_path
                except serializers.ValidationError as e:
                    # Append the URL of missing Artifact to the error message
                    e.detail[0] = "%s %s" % (e.detail[0], url)
                    raise e
        data['artifacts'] = artifacts
        return data
class AptPublicationSerializer(PublicationSerializer):
    """
    A Serializer for AptPublication.
    """

    simple = BooleanField(
        help_text="Activate simple publishing mode (all packages in one release component).",
        default=False,
    )
    structured = BooleanField(help_text="Activate structured publishing mode.", default=False)
    signing_service = RelatedField(
        help_text="Sign Release files with this signing key",
        many=False,
        queryset=AptReleaseSigningService.objects.all(),
        view_name="signing-services-detail",
        required=False,
    )

    def validate(self, data):
        """
        Check that the publishing modes are compatible.
        """
        data = super().validate(data)
        if not data["simple"] and not data["structured"]:
            raise ValidationError("one of simple or structured publishing mode must be selected")
        return data

    class Meta:
        fields = PublicationSerializer.Meta.fields + ("simple", "structured", "signing_service")
        model = AptPublication
Exemple #3
0
class TagOperationSerializer(serializers.Serializer):
    """
    A base serializer for tagging and untagging manifests.
    """

    repository = RelatedField(required=True,
                              view_name='repositories-detail',
                              queryset=Repository.objects.all(),
                              help_text='A URI of the repository.')
    tag = serializers.CharField(required=True, help_text='A tag name')

    def validate(self, data):
        """
        Validate data passed through a request call.

        Check if a repository has got a reference to a latest repository version. A
        new dictionary object is initialized by the passed data and altered by a latest
        repository version.
        """
        new_data = {}
        new_data.update(data)

        latest_version = RepositoryVersion.latest(data['repository'])
        if not latest_version:
            raise serializers.ValidationError(
                _("The latest repository version of '{}' was not found".format(
                    data['repository'])))

        new_data['latest_version'] = latest_version
        return new_data
Exemple #4
0
class RpmRepositorySerializer(RepositorySerializer):
    """
    Serializer for Rpm Repositories.
    """

    metadata_signing_service = RelatedField(
        help_text="A reference to an associated signing service.",
        view_name="signing-services-detail",
        queryset=AsciiArmoredDetachedSigningService.objects.all(),
        many=False,
        required=False,
        allow_null=True,
    )
    retain_package_versions = serializers.IntegerField(
        help_text=_(
            "The number of versions of each package to keep in the repository; "
            "older versions will be purged. The default is '0', which will disable "
            "this feature and keep all versions of each package."
        ),
        min_value=0,
        required=False,
    )

    class Meta:
        fields = RepositorySerializer.Meta.fields + (
            "metadata_signing_service",
            "retain_package_versions",
        )
        model = RpmRepository
Exemple #5
0
class FileContentSerializer(ContentSerializer):
    """
    Serializer for File Content.
    """

    relative_path = serializers.CharField(
        help_text="Relative location of the file within the repository")
    artifact = RelatedField(
        view_name='artifacts-detail',
        help_text="Artifact file representing the physical content",
        queryset=Artifact.objects.all())

    def validate(self, data):
        """Validate the FileContent data."""
        artifact = data['artifact']
        content = FileContent.objects.filter(
            digest=artifact.sha256, relative_path=data['relative_path'])

        if content.exists():
            raise serializers.ValidationError(
                _("There is already a file content with relative "
                  "path '{path}' and artifact '{artifact}'.").format(
                      path=data["relative_path"],
                      artifact=self.initial_data["artifact"]))
        return data

    class Meta:
        fields = tuple(set(ContentSerializer.Meta.fields) -
                       {'artifacts'}) + ('relative_path', 'artifact')
        model = FileContent
Exemple #6
0
class CollectionVersionSignatureSerializer(NoArtifactContentSerializer):
    """
    A serializer for signature models.
    """

    signed_collection = DetailRelatedField(
        help_text=_("The content this signature is pointing to."),
        view_name_pattern=r"content(-.*/.*)-detail",
        queryset=CollectionVersion.objects.all(),
    )
    pubkey_fingerprint = serializers.CharField(help_text=_("The fingerprint of the public key."))
    signing_service = RelatedField(
        help_text=_("The signing service used to create the signature."),
        view_name="signing-services-detail",
        queryset=SigningService.objects.all(),
        allow_null=True,
    )

    class Meta:
        model = CollectionVersionSignature
        fields = NoArtifactContentSerializer.Meta.fields + (
            "signed_collection",
            "pubkey_fingerprint",
            "signing_service",
        )
Exemple #7
0
class PackageCategorySerializer(NoArtifactContentSerializer):
    """
    PackageCategory serializer.
    """

    id = serializers.CharField(help_text=_("Category id."), )
    name = serializers.CharField(help_text=_("Category name."),
                                 allow_blank=True)
    description = serializers.CharField(help_text=_("Category description."),
                                        allow_blank=True)
    display_order = serializers.IntegerField(
        help_text=_("Category display order."), allow_null=True)
    group_ids = serializers.JSONField(help_text=_("Category group list."),
                                      allow_null=True)
    desc_by_lang = serializers.JSONField(
        help_text=_("Category description by language."), allow_null=True)
    name_by_lang = serializers.JSONField(
        help_text=_("Category name by language."), allow_null=True)
    digest = serializers.CharField(help_text=_("Category digest."), )
    packagegroups = RelatedField(
        help_text=_("PackageGroups related to this category."),
        allow_null=True,
        required=False,
        queryset=PackageGroup.objects.all(),
        many=True,
        view_name='content-rpm/packagegroups-detail')

    class Meta:
        fields = NoArtifactContentSerializer.Meta.fields + (
            'id', 'name', 'description', 'display_order', 'group_ids',
            'desc_by_lang', 'name_by_lang', 'digest', 'packagegroups')
        model = PackageCategory
Exemple #8
0
class FileContentSerializer(ContentSerializer):
    """
    Serializer for File Content.
    """

    relative_path = serializers.CharField(
        help_text="Relative location of the file within the repository")
    artifact = RelatedField(
        view_name='artifacts-detail',
        help_text="Artifact file representing the physical content",
        queryset=Artifact.objects.all())

    class Meta:
        fields = tuple(set(ContentSerializer.Meta.fields) -
                       {'artifacts'}) + ('relative_path', 'artifact')
        model = FileContent
Exemple #9
0
class CollectionVersionSignatureSerializer(NoArtifactContentUploadSerializer):
    """
    A serializer for signature models.
    """

    signed_collection = DetailRelatedField(
        help_text=_("The content this signature is pointing to."),
        view_name_pattern=r"content(-.*/.*)-detail",
        queryset=CollectionVersion.objects.all(),
    )
    pubkey_fingerprint = serializers.CharField(
        help_text=_("The fingerprint of the public key."),
        read_only=True,
    )
    signing_service = RelatedField(
        help_text=_("The signing service used to create the signature."),
        view_name="signing-services-detail",
        read_only=True,
        allow_null=True,
    )

    def __init__(self, *args, **kwargs):
        """Ensure `file` field is required."""
        super().__init__(*args, **kwargs)
        self.fields["file"].required = True

    def validate(self, data):
        """
        Verify the signature is valid before creating it.
        """
        data = super().validate(data)

        if "request" not in self.context:
            # Validate is called twice, first on the viewset, and second on the create task
            # data should be set up properly on the second time, when request isn't in context
            data = verify_signature_upload(data)

        return data

    class Meta:
        model = CollectionVersionSignature
        fields = NoArtifactContentUploadSerializer.Meta.fields + (
            "signed_collection",
            "pubkey_fingerprint",
            "signing_service",
        )
Exemple #10
0
class CookbookPackageContentSerializer(ContentSerializer):
    """Serializer for the cookbook content."""

    name = serializers.CharField(help_text=_("name of the cookbook"))
    version = serializers.CharField(help_text=_("version of the cookbook"),
                                    required=False)
    dependencies = serializers.JSONField(
        help_text=_("dependencies of the cookbook"), read_only=True)
    artifact = RelatedField(view_name='artifacts-detail',
                            help_text=_("tar archive containing the cookbook"),
                            queryset=Artifact.objects.all())
    artifacts = None

    class Meta:
        fields = tuple(field for field in ContentSerializer.Meta.fields if field != 'artifacts') \
            + ('name', 'version', 'dependencies', 'artifact')
        model = CookbookPackageContent
Exemple #11
0
class CookbookPublicationSerializer(PublicationSerializer):
    """
    Serializer for Cookbook Publications.
    """

    distributions = RelatedField(
        help_text=_(
            "This publication is currently being served as defined by these distributions."
        ),
        source="cookbook_cookbookdistribution",
        many=True,
        read_only=True,
        view_name="distributions-cookbook/cookbook-detail",
    )

    class Meta:
        fields = PublicationSerializer.Meta.fields + ("distributions",)
        model = CookbookPublication
class ContainerRepositorySerializer(RepositorySerializer):
    """
    Serializer for Container Repositories.
    """

    manifest_signing_service = RelatedField(
        help_text="A reference to an associated signing service.",
        view_name="signing-services-detail",
        queryset=models.ManifestSigningService.objects.all(),
        many=False,
        required=False,
        allow_null=True,
    )

    class Meta:
        fields = RepositorySerializer.Meta.fields + (
            "manifest_signing_service", )
        model = models.ContainerRepository
class AnsibleRoleVersionSerializer(ContentSerializer):
    """
    A serializer for Ansible Role versions.
    """

    _href = NestedIdentityField(
        view_name='versions-detail',
        parent_lookup_kwargs={'role_pk': 'role__pk'},
    )

    artifact = RelatedField(
        view_name='artifacts-detail',
        help_text="Artifact file representing the physical content",
        queryset=Artifact.objects.all())

    version = serializers.CharField()

    class Meta:
        fields = ('_href', 'type', 'version', 'artifact')
        model = AnsibleRoleVersion
Exemple #14
0
class PackageGroupSerializer(NoArtifactContentSerializer):
    """
    PackageGroup serializer.
    """

    id = serializers.CharField(help_text=_("PackageGroup id."), )
    default = serializers.BooleanField(help_text=_("PackageGroup default."),
                                       required=False)
    user_visible = serializers.BooleanField(
        help_text=_("PackageGroup user visibility."), required=False)
    display_order = serializers.IntegerField(
        help_text=_("PackageGroup display order."), allow_null=True)
    name = serializers.CharField(help_text=_("PackageGroup name."),
                                 allow_null=True)
    description = serializers.CharField(
        help_text=_("PackageGroup description."), allow_null=True)
    packages = serializers.JSONField(help_text=_("PackageGroup package list."),
                                     allow_null=True)
    biarch_only = serializers.BooleanField(
        help_text=_("PackageGroup biarch only."), required=False)
    desc_by_lang = serializers.JSONField(
        help_text=_("PackageGroup description by language."), allow_null=True)
    name_by_lang = serializers.JSONField(
        help_text=_("PackageGroup name by language."), allow_null=True)
    digest = serializers.CharField(help_text=_("PackageGroup digest."),
                                   allow_null=True)
    related_packages = RelatedField(
        help_text=_("Packages related to this PackageGroup."),
        allow_null=True,
        required=False,
        queryset=Package.objects.all(),
        many=True,
        view_name='content-rpm/packages-detail')

    class Meta:
        fields = NoArtifactContentSerializer.Meta.fields + (
            'id', 'default', 'user_visible', 'display_order', 'name',
            'description', 'packages', 'biarch_only', 'desc_by_lang',
            'name_by_lang', 'digest', 'related_packages')
        model = PackageGroup
Exemple #15
0
class AnsibleRepositorySignatureSerializer(serializers.Serializer):
    """
    A serializer for the signing action.
    """

    content_units = serializers.ListField(
        required=True,
        help_text=_(
            "List of collection version hrefs to sign, use * to sign all content in repository"
        ),
    )
    signing_service = RelatedField(
        required=True,
        view_name="signing-services-detail",
        queryset=SigningService.objects.all(),
        help_text=_("A signing service to use to sign the collections"),
    )

    def validate_content_units(self, value):
        """Make sure the list is correctly formatted."""
        if len(value) > 1 and "*" in value:
            raise serializers.ValidationError("Cannot supply content units and '*'.")
        return value
Exemple #16
0
class DockerDistributionSerializer(ModelSerializer):
    """
    A serializer for DockerDistribution.
    """

    _href = 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 = 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 = 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 = 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 = 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
Exemple #17
0
class OCIBuildImageSerializer(serializers.Serializer):
    """
    Serializer for building an OCI container image from a Containerfile.

    The Containerfile can either be specified via an artifact url, or a new file can be uploaded.
    A repository must be specified, to which the container image content will be added.
    """

    containerfile_artifact = RelatedField(
        many=False,
        lookup_field="pk",
        view_name="artifacts-detail",
        queryset=Artifact.objects.all(),
        help_text=_("Artifact representing the Containerfile that should be used to run buildah."),
    )
    containerfile = serializers.FileField(
        help_text=_("An uploaded Containerfile that should be used to run buildah."),
        required=False,
    )
    tag = serializers.CharField(
        required=False, default="latest", help_text="A tag name for the new image being built."
    )
    artifacts = serializers.JSONField(
        required=False,
        help_text="A JSON string where each key is an artifact href and the value is it's "
        "relative path (name) inside the /pulp_working_directory of the build container "
        "executing the Containerfile.",
    )

    def __init__(self, *args, **kwargs):
        """Initializer for OCIBuildImageSerializer."""
        super().__init__(*args, **kwargs)
        self.fields["containerfile_artifact"].required = False

    def validate(self, data):
        """Validates that all the fields make sense."""
        data = super().validate(data)

        if "containerfile" in data:
            if "containerfile_artifact" in data:
                raise serializers.ValidationError(
                    _("Only one of 'containerfile' and 'containerfile_artifact' may be specified.")
                )
            data["containerfile_artifact"] = Artifact.init_and_validate(data.pop("containerfile"))
        elif "containerfile_artifact" not in data:
            raise serializers.ValidationError(
                _("'containerfile' or 'containerfile_artifact' must " "be specified.")
            )
        artifacts = {}
        if "artifacts" in data:
            for url, relative_path in data["artifacts"].items():
                if os.path.isabs(relative_path):
                    raise serializers.ValidationError(
                        _("Relative path cannot start with '/'. " "{0}").format(relative_path)
                    )
                artifactfield = RelatedField(
                    view_name="artifacts-detail",
                    queryset=Artifact.objects.all(),
                    source="*",
                    initial=url,
                )
                try:
                    artifact = artifactfield.run_validation(data=url)
                    artifacts[artifact.pk] = relative_path
                except serializers.ValidationError as e:
                    # Append the URL of missing Artifact to the error message
                    e.detail[0] = "%s %s" % (e.detail[0], url)
                    raise e
        data["artifacts"] = artifacts
        return data

    class Meta:
        fields = (
            "containerfile_artifact",
            "containerfile",
            "repository",
            "tag",
            "artifacts",
        )
Exemple #18
0
class ContainerDistributionSerializer(DistributionSerializer):
    """
    A serializer for ContainerDistribution.
    """

    registry_path = RegistryPathField(
        source="base_path",
        read_only=True,
        help_text=_(
            "The Registry hostame/name/ to use with docker pull command defined by "
            "this distribution."
        ),
    )
    content_guard = DetailRelatedField(
        required=False,
        help_text=_("An optional content-guard. If none is specified, a default one will be used."),
        view_name=r"contentguards-container/content-redirect-detail",
        queryset=models.ContentRedirectContentGuard.objects.all(),
        allow_null=False,
    )
    namespace = RelatedField(
        required=False,
        read_only=True,
        view_name="pulp_container/namespaces-detail",
        help_text=_("Namespace this distribution belongs to."),
    )
    description = serializers.CharField(
        help_text=_("An optional description."), required=False, allow_null=True
    )
    repository_version = RepositoryVersionRelatedField(
        required=False, help_text=_("RepositoryVersion to be served"), allow_null=True
    )

    def validate(self, data):
        """
        Validate the ContainterDistribution.

        Make sure there is an instance of ContentRedirectContentGuard always present in validated
        data.
        Validate that the distribution  is not serving a repository versions of a push repository.
        """
        validated_data = super().validate(data)
        if "content_guard" not in validated_data:
            validated_data["content_guard"] = ContentRedirectContentGuardSerializer.get_or_create(
                {"name": "content redirect"}
            )
        if "repository_version" in validated_data:
            repository = validated_data["repository_version"].repository.cast()
            if repository.PUSH_ENABLED:
                raise serializers.ValidationError(
                    _(
                        "A container push repository cannot be distributed by specifying a "
                        "repository version."
                    )
                )

        if "base_path" in validated_data:
            base_path = validated_data["base_path"]
            namespace_name = base_path.split("/")[0]

            if "namespace" in validated_data:
                if validated_data["namespace"].name != namespace_name:
                    raise serializers.ValidationError(
                        _("Selected namespace does not match first component of base_path.")
                    )
            else:
                validated_data["namespace"] = ContainerNamespaceSerializer.get_or_create(
                    {"name": namespace_name}
                )
        return validated_data

    class Meta:
        model = models.ContainerDistribution
        fields = tuple(set(DistributionSerializer.Meta.fields) - {"base_url"}) + (
            "repository_version",
            "registry_path",
            "namespace",
            "private",
            "description",
        )
Exemple #19
0
class RpmRepositorySerializer(RepositorySerializer):
    """
    Serializer for Rpm Repositories.
    """

    autopublish = serializers.BooleanField(
        help_text=_(
            "Whether to automatically create publications for new repository versions, "
            "and update any distributions pointing to this repository."),
        default=False,
        required=False,
    )
    metadata_signing_service = RelatedField(
        help_text="A reference to an associated signing service.",
        view_name="signing-services-detail",
        queryset=AsciiArmoredDetachedSigningService.objects.all(),
        many=False,
        required=False,
        allow_null=True,
    )
    retain_package_versions = serializers.IntegerField(
        help_text=
        _("The number of versions of each package to keep in the repository; "
          "older versions will be purged. The default is '0', which will disable "
          "this feature and keep all versions of each package."),
        min_value=0,
        required=False,
    )
    metadata_checksum_type = serializers.ChoiceField(
        help_text=_("The checksum type for metadata."),
        choices=CHECKSUM_CHOICES,
        default=CHECKSUM_TYPES.SHA256,
    )
    package_checksum_type = serializers.ChoiceField(
        help_text=_("The checksum type for packages."),
        choices=CHECKSUM_CHOICES,
        default=CHECKSUM_TYPES.SHA256,
    )
    gpgcheck = serializers.IntegerField(
        max_value=1,
        min_value=0,
        default=0,
        required=False,
        help_text=_("An option specifying whether a client should perform "
                    "a GPG signature check on packages."),
    )
    repo_gpgcheck = serializers.IntegerField(
        max_value=1,
        min_value=0,
        default=0,
        required=False,
        help_text=_("An option specifying whether a client should perform "
                    "a GPG signature check on the repodata."),
    )
    sqlite_metadata = serializers.BooleanField(
        default=False,
        required=False,
        help_text=_(
            "An option specifying whether Pulp should generate SQLite metadata."
        ),
    )

    def validate(self, data):
        """Validate data."""
        for field in ("metadata_checksum_type", "package_checksum_type"):
            if field in data and data[
                    field] not in settings.ALLOWED_CONTENT_CHECKSUMS:
                raise serializers.ValidationError(
                    {field: _(ALLOWED_CHECKSUM_ERROR_MSG)})

        validated_data = super().validate(data)
        return validated_data

    class Meta:
        fields = RepositorySerializer.Meta.fields + (
            "autopublish",
            "metadata_signing_service",
            "retain_package_versions",
            "metadata_checksum_type",
            "package_checksum_type",
            "gpgcheck",
            "repo_gpgcheck",
            "sqlite_metadata",
        )
        model = RpmRepository
Exemple #20
0
class PackageSerializer(ContentSerializer):
    """
    A Serializer for Package.

    Add serializers for the new fields defined in Package and add those fields to the Meta class
    keeping fields from the parent class as well. Provide help_text.
    """

    artifact = RelatedField(
        view_name='artifacts-detail',
        help_text="Artifact file representing the physical content",
        queryset=Artifact.objects.all())

    name = serializers.CharField(help_text=_("Name of the package"), )
    epoch = serializers.CharField(
        help_text=_("The package's epoch"),
        allow_blank=True,
        required=False,
    )
    version = serializers.CharField(
        help_text=_("The version of the package. For example, '2.8.0'"), )
    release = serializers.CharField(help_text=_(
        "The release of a particular version of the package. e.g. '1.el7' or '3.f24'"
    ), )
    arch = serializers.CharField(help_text=_(
        "The target architecture for a package."
        "For example, 'x86_64', 'i686', or 'noarch'"), )

    pkgId = serializers.CharField(
        help_text=_("Checksum of the package file"), )
    checksum_type = serializers.CharField(
        help_text=_("Type of checksum, e.g. 'sha256', 'md5'"), )

    summary = serializers.CharField(
        help_text=_("Short description of the packaged software"),
        allow_blank=True,
        required=False,
    )
    description = serializers.CharField(
        help_text=_("In-depth description of the packaged software"),
        allow_blank=True,
        required=False,
    )
    url = serializers.CharField(
        help_text=_("URL with more information about the packaged software"),
        allow_blank=True,
        required=False,
    )

    changelogs = serializers.CharField(
        help_text=_("Changelogs that package contains"),
        default="[]",
        required=False)
    files = serializers.CharField(help_text=_("Files that package contains"),
                                  default="[]",
                                  required=False)

    requires = serializers.CharField(
        help_text=_("Capabilities the package requires"),
        default="[]",
        required=False)
    provides = serializers.CharField(
        help_text=_("Capabilities the package provides"),
        default="[]",
        required=False)
    conflicts = serializers.CharField(
        help_text=_("Capabilities the package conflicts"),
        default="[]",
        required=False)
    obsoletes = serializers.CharField(
        help_text=_("Capabilities the package obsoletes"),
        default="[]",
        required=False)
    suggests = serializers.CharField(
        help_text=_("Capabilities the package suggests"),
        default="[]",
        required=False)
    enhances = serializers.CharField(
        help_text=_("Capabilities the package enhances"),
        default="[]",
        required=False)
    recommends = serializers.CharField(
        help_text=_("Capabilities the package recommends"),
        default="[]",
        required=False)
    supplements = serializers.CharField(
        help_text=_("Capabilities the package supplements"),
        default="[]",
        required=False)

    location_base = serializers.CharField(
        help_text=_("Base location of this package"),
        allow_blank=True,
        required=False)
    location_href = serializers.CharField(
        help_text=_("Relative location of package to the repodata"), )

    rpm_buildhost = serializers.CharField(
        help_text=_("Hostname of the system that built the package"),
        allow_blank=True,
        required=False)
    rpm_group = serializers.CharField(help_text=_(
        "RPM group (See: http://fedoraproject.org/wiki/RPMGroups)"),
                                      allow_blank=True,
                                      required=False)
    rpm_license = serializers.CharField(help_text=_(
        "License term applicable to the package software (GPLv2, etc.)"),
                                        allow_blank=True,
                                        required=False)
    rpm_packager = serializers.CharField(
        help_text=_("Person or persons responsible for creating the package"),
        allow_blank=True,
        required=False)
    rpm_sourcerpm = serializers.CharField(help_text=_(
        "Name of the source package (srpm) the package was built from"),
                                          allow_blank=True,
                                          required=False)
    rpm_vendor = serializers.CharField(
        help_text=_("Name of the organization that produced the package"),
        allow_blank=True,
        required=False)
    rpm_header_start = serializers.IntegerField(
        help_text=_("First byte of the header"), )
    rpm_header_end = serializers.IntegerField(
        help_text=_("Last byte of the header"), )

    size_archive = serializers.IntegerField(help_text=_(
        "Size, in bytes, of the archive portion of the original package file"))
    size_installed = serializers.IntegerField(help_text=_(
        "Total size, in bytes, of every file installed by this package"))
    size_package = serializers.IntegerField(
        help_text=_("Size, in bytes, of the package"))

    time_build = serializers.IntegerField(
        help_text=_("Time the package was built in seconds since the epoch"))
    time_file = serializers.IntegerField(
        help_text=_("The 'file' time attribute in the primary XML - "
                    "file mtime in seconds since the epoch."))

    def create(self, validated_data):
        """
        Create a Package.

        Overriding default create() to deal with artifact properly.

        Args:
            validated_data (dict): Data used to create the Package

        Returns:
            models.Package: The created Package

        """
        artifact = validated_data.pop('artifact')

        package = Package.objects.create(**validated_data)
        ca = ContentArtifact(artifact=artifact,
                             content=package,
                             relative_path=package.filename)
        ca.save()

        return package

    class Meta:
        fields = tuple(set(ContentSerializer.Meta.fields) - {'artifacts'}) + (
            'artifact', 'name', 'epoch', 'version', 'release', 'arch', 'pkgId',
            'checksum_type', 'summary', 'description', 'url', 'changelogs',
            'files', 'requires', 'provides', 'conflicts', 'obsoletes',
            'suggests', 'enhances', 'recommends', 'supplements',
            'location_base', 'location_href', 'rpm_buildhost', 'rpm_group',
            'rpm_license', 'rpm_packager', 'rpm_sourcerpm', 'rpm_vendor',
            'rpm_header_start', 'rpm_header_end', 'size_archive',
            'size_installed', 'size_package', 'time_build', 'time_file')
        model = Package
class RepositorySignSerializer(serializers.Serializer):
    """
    Serializer for container images signing.
    """

    manifest_signing_service = RelatedField(
        required=False,
        many=False,
        view_name="signing-services-detail",
        queryset=models.ManifestSigningService.objects.all(),
        help_text=
        _("A signing service to sign with. This will override a signing service set on the repo."
          ),
        allow_null=True,
    )

    # Ask for the future_base_path for synced repos - this should match future/existing distribution
    # otherwise client verification can fail, it looks at 'docker-reference' in the signature json
    future_base_path = serializers.CharField(
        required=False,
        help_text=_(
            "Future base path content will be distributed at for sync repos"),
    )
    tags_list = serializers.ListField(help_text=_("A list of tags to sign."),
                                      required=False)

    def validate(self, data):
        """Ensure that future_base_path is provided for synced repos."""

        data = super().validate(data)

        repository = Repository.objects.get(
            pk=self.context["repository_pk"]).cast()
        try:
            signing_service = repository.manifest_signing_service
        except KeyError:
            signing_service = None

        if "manifest_signing_service" not in data and not signing_service:
            raise serializers.ValidationError({
                "manifest_signing_service":
                _("This field is required since a signing_service is not set on the repo."
                  )
            })

        if repository.PUSH_ENABLED:
            if "future_base_path" in data:
                raise serializers.ValidationError({
                    "future_base_path":
                    _("This field cannot be set since this is a push repo type."
                      )
                })
            data["future_base_path"] = repository.distributions.first(
            ).base_path
        else:
            if "future_base_path" not in data:
                raise serializers.ValidationError({
                    "future_base_path":
                    _("This field is required since this is a sync repo type.")
                })

        return data
Exemple #22
0
class PackageEnvironmentSerializer(NoArtifactContentSerializer):
    """
    PackageEnvironment serializer.
    """

    id = serializers.CharField(
        help_text=_("Environment id."),
    )
    name = serializers.CharField(
        help_text=_("Environment name."),
        allow_null=True
    )
    description = serializers.CharField(
        help_text=_("Environment description."),
        allow_null=True
    )
    display_order = serializers.IntegerField(
        help_text=_("Environment display order."),
        allow_null=True
    )
    group_ids = serializers.JSONField(
        help_text=_("Environment group list."),
        allow_null=True
    )
    option_ids = serializers.JSONField(
        help_text=_("Environment option ids"),
        allow_null=True
    )
    desc_by_lang = serializers.JSONField(
        help_text=_("Environment description by language."),
        allow_null=True
    )
    name_by_lang = serializers.JSONField(
        help_text=_("Environment name by language."),
        allow_null=True
    )
    digest = serializers.CharField(
        help_text=_("Environment digest."),
        allow_null=True
    )
    packagegroups = RelatedField(
        help_text=_("Groups related to this Environment."),
        allow_null=True,
        required=False,
        queryset=PackageGroup.objects.all(),
        many=True,
        view_name='content-rpm/packagegroups-detail'
    )
    optionalgroups = RelatedField(
        help_text=_("Groups optionally related to this Environment."),
        allow_null=True,
        required=False,
        queryset=PackageGroup.objects.all(),
        many=True,
        view_name='content-rpm/packagegroups-detail'
    )

    class Meta:
        fields = (
            'id', 'name', 'description', 'display_order',
            'group_ids', 'option_ids', 'desc_by_lang', 'name_by_lang',
            'digest', 'packagegroups', 'optionalgroups'
        )
        model = PackageEnvironment