Skip to content

Commit

Permalink
Enable filtering by content
Browse files Browse the repository at this point in the history
closes pulp#2952
  • Loading branch information
lubosmj committed Aug 12, 2022
1 parent 4740c55 commit 390720a
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGES/2952.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Introduced the ``with_content`` query parameter that filters distributions by the specified content
unit.
62 changes: 60 additions & 2 deletions pulpcore/app/viewsets/custom_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@
This module contains custom filters that might be used by more than one ViewSet.
"""
import re

from collections import defaultdict
from itertools import chain
from gettext import gettext as _
from urllib.parse import urlparse
from uuid import UUID

from django.urls import Resolver404, resolve
from django.db.models import ObjectDoesNotExist
from django_filters import BaseInFilter, CharFilter, DateTimeFilter, Filter
from django_filters.fields import IsoDateTimeField
from rest_framework import serializers
from rest_framework.serializers import ValidationError as DRFValidationError

from pulpcore.app.models import ContentArtifact, Label, RepositoryVersion
from pulpcore.app.models import ContentArtifact, Label, RepositoryVersion, Publication
from pulpcore.app.viewsets import NamedModelViewSet


Expand Down Expand Up @@ -311,7 +315,7 @@ def filter(self, qs, value):
"""
Args:
qs (django.db.models.query.QuerySet): The Model queryset
value (string): label search querry
value (string): label search query
Returns:
Queryset of the Models filtered by label(s)
Expand Down Expand Up @@ -351,3 +355,57 @@ def filter(self, qs, value):
qs = qs.filter(pulp_labels__in=labels)

return qs


class DistributionWithContentFilter(Filter):
"""A Filter class enabling filtering by content units served by distributions."""

def __init__(self, *args, **kwargs):
"""Initialize a help message for the filter."""
kwargs.setdefault(
"help_text", _("Filter distributions based on the content served by them")
)
super().__init__(*args, **kwargs)

def filter(self, qs, value):
"""Filter distributions by the provided content unit."""
if value is None:
return qs

# the same repository version can be referenced from multiple distributions; therefore,
# we are later appending distributions to a list value representing a single repository
# version
versions_distributions = defaultdict(list)

for dist in qs.exclude(publication=None).values("publication__repository_version", "pk"):
versions_distributions[dist["publication__repository_version"]].append(dist["pk"])

for dist in qs.exclude(repository_version=None).values("repository_version", "pk"):
if not dist.cast().SERVE_FROM_PUBLICATION:
versions_distributions[dist["repository_version"]].append(dist["pk"])

for dist in qs.exclude(repository=None).prefetch_related("repository__versions"):
if dist.cast().SERVE_FROM_PUBLICATION:
versions = dist.repository.versions.values_list("pk", flat=True)
publications = Publication.objects.filter(
repository_version__in=versions, complete=True
)

try:
publication = publications.select_related("repository_version").latest(
"repository_version", "pulp_created"
)
except ObjectDoesNotExist:
pass
else:
repo_version = publication.repository_version
versions_distributions[repo_version.pk].append(dist.pk)
else:
repo_version = dist.repository.latest_version()
versions_distributions[repo_version.pk].append(dist.pk)

content = NamedModelViewSet.get_resource(value)
versions = RepositoryVersion.objects.with_content([content.pk]).values_list("pk", flat=True)

distributions = chain.from_iterable(versions_distributions[version] for version in versions)
return qs.filter(pk__in=distributions)
2 changes: 2 additions & 0 deletions pulpcore/app/viewsets/publication.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
)
from pulpcore.app.viewsets.base import DATETIME_FILTER_OPTIONS, NAME_FILTER_OPTIONS
from pulpcore.app.viewsets.custom_filters import (
DistributionWithContentFilter,
IsoDateTimeFilter,
LabelSelectFilter,
RepositoryVersionFilter,
Expand Down Expand Up @@ -327,6 +328,7 @@ class DistributionFilter(BaseFilterSet):
name = filters.CharFilter()
base_path = filters.CharFilter()
pulp_label_select = LabelSelectFilter()
with_content = DistributionWithContentFilter()

class Meta:
model = Distribution
Expand Down

0 comments on commit 390720a

Please sign in to comment.