Repository: pulp/pulpcore

Issue:
Bump minor version
[noissue]


Discussion:

Resolving patch:
diff --git a/pulpcore/app/viewsets/custom_filters.py b/pulpcore/app/viewsets/custom_filters.py
--- a/pulpcore/app/viewsets/custom_filters.py
+++ b/pulpcore/app/viewsets/custom_filters.py
@@ -41,6 +41,33 @@ def filter(self, qs, value):
         return qs.filter(reserved_resources_record__resource=value)
 
 
+class CreatedResourcesFilter(Filter):
+    """
+    Filter used to get tasks by created resources.
+
+    Created resources contain a reference to newly created repository
+    versions, distributions, etc.
+    """
+
+    def filter(self, qs, value):
+        """
+        Args:
+            qs (django.db.models.query.QuerySet): The QuerySet to filter
+            value (string): The content href to filter by
+
+        Returns:
+            Queryset of the content contained within the specified created resource
+        """
+
+        if value is None:
+            return qs
+
+        match = resolve(value)
+        resource = NamedModelViewSet.get_resource(value, match.func.cls.queryset.model)
+
+        return qs.filter(created_resources__object_id=resource.pk)
+
+
 class HyperlinkRelatedFilter(Filter):
     """
     Enables a user to filter by a foreign key using that FK's href
diff --git a/pulpcore/app/viewsets/task.py b/pulpcore/app/viewsets/task.py
--- a/pulpcore/app/viewsets/task.py
+++ b/pulpcore/app/viewsets/task.py
@@ -20,6 +20,7 @@
     HyperlinkRelatedFilter,
     IsoDateTimeFilter,
     ReservedResourcesFilter,
+    CreatedResourcesFilter,
 )
 from pulpcore.constants import TASK_INCOMPLETE_STATES
 from pulpcore.tasking.util import cancel as cancel_task
@@ -33,6 +34,7 @@ class TaskFilter(BaseFilterSet):
     finished_at = IsoDateTimeFilter(field_name='finished_at')
     parent = HyperlinkRelatedFilter()
     reserved_resources_record = ReservedResourcesFilter()
+    created_resources = CreatedResourcesFilter()
 
     class Meta:
         model = Task
@@ -43,7 +45,8 @@ class Meta:
             'started_at': DATETIME_FILTER_OPTIONS,
             'finished_at': DATETIME_FILTER_OPTIONS,
             'parent': ['exact'],
-            'reserved_resources_record': ['exact']
+            'reserved_resources_record': ['exact'],
+            'created_resources': ['exact']
         }
 
 


Test patch:
diff --git a/pulpcore/tests/functional/api/test_tasks.py b/pulpcore/tests/functional/api/test_tasks.py
--- a/pulpcore/tests/functional/api/test_tasks.py
+++ b/pulpcore/tests/functional/api/test_tasks.py
@@ -148,7 +148,7 @@ def filter_tasks(self, criteria):
 
 
 class FilterTaskCreatedResourcesTestCase(unittest.TestCase):
-    """Perform filtering over task resources.
+    """Perform filtering over the task's field created_resources.
 
     This test targets the following issue:
 
@@ -220,3 +220,44 @@ def test_02_filter_tasks_by_non_existing_resources(self):
         }
         with self.assertRaises(HTTPError):
             self.client.get(TASKS_PATH, params=filter_params)
+
+
+class FilterTaskCreatedResourcesContentTestCase(unittest.TestCase):
+    """Perform filtering for contents of created resources.
+
+    This test targets the following issue:
+
+    * `Pulp #4931 <https://pulp.plan.io/issues/4931>`_
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        """Create class-wide variables."""
+        cls.client = api.Client(config.get_config(), api.page_handler)
+
+        cls.repository = cls.client.post(REPO_PATH, gen_repo())
+        response = cls.client.post(cls.repository['_versions_href'])
+        cls.task = cls.client.get(response['task'])
+
+    @classmethod
+    def tearDownClass(cls):
+        """Clean created resources."""
+        cls.client.delete(cls.repository['_href'])
+        cls.client.delete(cls.task['_href'])
+
+    def test_01_filter_tasks_by_created_resources(self):
+        """Filter all tasks by a particular created resource."""
+        filter_params = {
+            'created_resources': self.task['created_resources'][0]
+        }
+        results = self.client.get(TASKS_PATH, params=filter_params)
+        self.assertEqual(len(results), 1, results)
+        self.assertEqual(self.task, results[0], results)
+
+    def test_02_filter_tasks_by_non_existing_resources(self):
+        """Filter all tasks by a non-existing reserved resource."""
+        filter_params = {
+            'created_resources': 'a_resource_should_be_never_named_like_this'
+        }
+        with self.assertRaises(HTTPError):
+            self.client.get(TASKS_PATH, params=filter_params)