예제 #1
0
class ContainerNamespaceDetailSerializer(ContainerNamespaceSerializer):
    groups = GroupPermissionField()

    class Meta:
        model = models.ContainerNamespace
        fields = namespace_fields + ('groups', )
        read_only_fields = ('name', 'my_permissions',)
예제 #2
0
class ContainerRepositorySerializer(serializers.ModelSerializer):
    pulp = serializers.SerializerMethodField()
    groups = GroupPermissionField()
    namespace = serializers.SerializerMethodField()
    id = serializers.SerializerMethodField()
    created = serializers.SerializerMethodField()
    updated = serializers.SerializerMethodField()

    # This serializer is purposfully refraining from using pulp fields directly
    # in the top level response body. This is because future versions of hub will have to
    # support indexing other registries and the API responses for a container
    # repository should make sense for containers hosted by pulp and containers
    # hosted by other registries.
    class Meta:
        model = models.ContainerDistribution
        read_only_fields = (
            'id',
            'name',
            # this field will return null on instances where hub is indexing a
            # different repo
            'pulp',
            'namespace',
            'description',
            'created',
            'updated')
        write_fields = ('groups', )

        fields = read_only_fields + write_fields

    def get_id(self, distro):
        return distro.pulp_id

    def get_created(self, distro):
        return distro.repository.pulp_created

    def get_updated(self, distro):
        return distro.repository.pulp_last_updated

    def get_namespace(self, distro):
        return distro.namespace.name

    def get_pulp(self, distro):
        repo = distro.repository

        return {
            'repository': {
                'pulp_id': repo.pulp_id,
                'pulp_type': repo.pulp_type,
                'version': repo.latest_version().number,
                'name': repo.name,
                'description': repo.description,
                'pulp_created': repo.pulp_created,
            },
            'distribution': {
                'pulp_id': distro.pulp_id,
                'name': distro.name,
                'pulp_created': distro.pulp_created,
                'base_path': distro.base_path,
            }
        }
예제 #3
0
class NamespaceSerializer(serializers.ModelSerializer):
    links = NamespaceLinkSerializer(many=True, required=False)

    groups = GroupPermissionField()

    class Meta:
        model = models.Namespace
        fields = ('id', 'name', 'company', 'email', 'avatar_url',
                  'description', 'links', 'groups', 'resources')

    # replace with a NamespaceNameSerializer and validate_name() ?
    def validate_name(self, name):
        if not name:
            raise ValidationError(
                detail={'name': "Attribute 'name' is required"})
        if not re.match(r'^[a-z0-9_]+$', name):
            raise ValidationError(
                detail={
                    'name':
                    'Name can only contain lower case letters, underscores and numbers'
                })
        if len(name) <= 2:
            raise ValidationError(
                detail={'name': 'Name must be longer than 2 characters'})
        if name.startswith('_'):
            raise ValidationError(
                detail={'name': "Name cannot begin with '_'"})
        return name

    @transaction.atomic
    def create(self, validated_data):
        links_data = validated_data.pop('links', [])

        instance = models.Namespace.objects.create(**validated_data)

        # create NamespaceLink objects if needed
        new_links = []
        for link_data in links_data:
            link_data["namespace"] = instance
            ns_link, created = models.NamespaceLink.objects.get_or_create(
                **link_data)
            new_links.append(ns_link)

        instance.links.set(new_links)
        return instance

    @transaction.atomic
    def update(self, instance, validated_data):
        links = validated_data.pop('links', None)

        if links is not None:
            instance.set_links(links)

        instance = super().update(instance, validated_data)
        instance.save()
        return instance
예제 #4
0
class SyncListSerializer(serializers.ModelSerializer):
    namespaces = serializers.SlugRelatedField(
        many=True, slug_field="name", queryset=models.Namespace.objects.all())

    collections = SyncListCollectionSummarySerializer(many=True)

    groups = GroupPermissionField()

    def _get_repository(self, repository_id):
        try:
            repository = AnsibleRepository.objects.get(pulp_id=repository_id)
            return repository
        except AnsibleRepository.DoesNotExist:
            errmsg = 'Repository "{pulp_id}" not found while creating synclist'
            raise ValidationError(errmsg.format(pulp_id=repository_id))

    def to_internal_value(self, data):
        repository_data = data.get("repository", None)
        if repository_data:
            data["repository"] = self._get_repository(repository_data)

        upstream_repository_data = data.get("upstream_repository", None)
        if upstream_repository_data:
            data["upstream_repository"] = self._get_repository(
                upstream_repository_data)
        else:
            # If not specified, use the default upstream repo
            data["upstream_repository"] = AnsibleRepository.objects.get(
                name=default_repo_name)
        return super().to_internal_value(data)

    @transaction.atomic
    def _create_repository(self, name):
        repository, created = AnsibleRepository.objects.get_or_create(
            name=name)
        if created:
            repository.save()
        return repository

    def _update_distribution(self, name_slug, repository):
        # Now the distro
        try:
            distribution, create = AnsibleDistribution.objects.get_or_create(
                name=name_slug,
                base_path=name_slug,
            )
        except Exception as exc:
            log.exception(exc)
            raise

        # Now update the Distribution to point to the new Repository
        distribution.repository = repository

        distribution.save()
        return distribution

    @transaction.atomic
    def create(self, validated_data):
        collections_data = validated_data.pop("collections")
        namespaces_data = validated_data.pop("namespaces")
        repository = validated_data.pop("repository", None)
        name = validated_data.get("name")

        if not repository:
            repository = self._create_repository(name)

        try:
            instance = models.SyncList.objects.create(repository=repository,
                                                      **validated_data)
        except IntegrityError as exc:
            raise ValidationError("Synclist already exists: %s" % exc)

        collections = []
        for collection_data in collections_data:
            try:
                collections.append(Collection.objects.get(**collection_data))
            except Collection.DoesNotExist:
                errmsg = (
                    'Collection "{namespace}.{name}" not found while creating synclist {synclist}'
                )
                raise ValidationError(
                    errmsg.format(
                        namespace=collection_data["namespace"],
                        name=collection_data["name"],
                        synclist=instance.name,
                    ))
        instance.collections.clear()
        instance.collections.set(collections)

        instance.namespaces.add(*namespaces_data)

        return instance

    @transaction.atomic
    def update(self, instance, validated_data):
        collections_data = validated_data.get("collections", [])

        groups_data = validated_data.get("groups")
        if groups_data:
            instance.groups = groups_data

        namespaces_data = validated_data.get("namespaces")
        if namespaces_data is not None:
            instance.namespaces.set(namespaces_data)

        instance.policy = validated_data.get("policy", instance.policy)

        instance.name = validated_data.get("name", instance.name)

        new_collections = []
        for collection_data in collections_data:
            try:
                new_collections.append(
                    Collection.objects.get(**collection_data))
            except Collection.DoesNotExist:
                errmsg = (
                    'Collection "{namespace}.{name}" not found while updating synclist {synclist}'
                )
                raise ValidationError(
                    errmsg.format(
                        namespace=collection_data["namespace"],
                        name=collection_data["name"],
                        synclist=instance.name,
                    ))
        instance.collections.set(new_collections)

        # if collection goes from empty to having something in it,
        # then we also need to point the associated distro to the synclist repo
        if instance.collections.all() and instance.repository:
            self._update_distribution(instance.name, instance.repository)
        else:
            # synclist is no longer including/excluding anything, so point back
            # at the default upstream repo
            self._update_distribution(instance.name,
                                      instance.upstream_repository)

        instance.save()

        return instance

    class Meta:
        model = models.SyncList
        fields = [
            "id",
            "name",
            "policy",
            "upstream_repository",
            "repository",
            "collections",
            "namespaces",
            "groups",
        ]

        read_only_fields = ("repository", )
예제 #5
0
class SyncListSerializer(serializers.ModelSerializer):
    namespaces = serializers.SlugRelatedField(
        many=True, slug_field="name", queryset=models.Namespace.objects.all())

    collections = SyncListCollectionSummarySerializer(many=True)

    groups = GroupPermissionField()

    @transaction.atomic
    def create(self, validated_data):
        collections_data = validated_data.pop("collections")

        namespaces_data = validated_data.pop("namespaces")

        instance = models.SyncList.objects.create(**validated_data)

        collections = []
        for collection_data in collections_data:
            try:
                collections.append(Collection.objects.get(**collection_data))
            except Collection.DoesNotExist:
                errmsg = \
                    'Collection "{namespace}.{name}" not found while creating synclist {synclist}'
                raise ValidationError(
                    errmsg.format(namespace=collection_data["namespace"],
                                  name=collection_data["name"],
                                  synclist=instance.name))

        instance.collections.clear()
        instance.collections.set(collections)

        instance.namespaces.add(*namespaces_data)

        return instance

    @transaction.atomic
    def update(self, instance, validated_data):
        collections_data = validated_data.get("collections")

        namespaces_data = validated_data.get("namespaces")

        instance.policy = validated_data.get("policy", instance.policy)

        instance.name = validated_data.get("name", instance.name)

        new_collections = []
        for collection_data in collections_data:
            try:
                new_collections.append(
                    Collection.objects.get(**collection_data))
            except Collection.DoesNotExist:
                errmsg = \
                    'Collection "{namespace}.{name}" not found while updating synclist {synclist}'
                raise ValidationError(
                    errmsg.format(namespace=collection_data["namespace"],
                                  name=collection_data["name"],
                                  synclist=instance.name))
        instance.collections.set(new_collections)
        instance.namespaces.set(namespaces_data)
        instance.save()
        instance.groups = validated_data.get('groups')

        return instance

    class Meta:
        model = models.SyncList
        fields = [
            "id",
            "name",
            "policy",
            "repository",
            "collections",
            "namespaces",
            "groups",
        ]