From 3e83e7471b57ed1a2c29a5402059e21da6db0666 Mon Sep 17 00:00:00 2001
From: Jose Castro Leon <jose.castro.leon@cern.ch>
Date: Thu, 12 Mar 2020 14:43:18 +0100
Subject: [PATCH] Allow os quota list query to filter by project

In the os quota list command, project parameter is completely ignored
ending up in a request to all projects and then all quotas. This patch
enables back the parameter and does a single call to quotas if specified.

Change-Id: Ie17c256e2bdc307dcd94ad5be7abdbffa776d369
Story: 2007422
Task: 39043
---
 openstackclient/common/quota.py               | 13 +++-
 .../tests/unit/common/test_quota.py           | 69 +++++++++++++++++++
 2 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py
index 37437344dc..71b8ea61f2 100644
--- a/openstackclient/common/quota.py
+++ b/openstackclient/common/quota.py
@@ -274,9 +274,18 @@ class ListQuota(command.Lister, BaseQuota):
         return parser
 
     def take_action(self, parsed_args):
-        projects = self.app.client_manager.identity.projects.list()
         result = []
-        project_ids = [getattr(p, 'id', '') for p in projects]
+        project_ids = []
+        if parsed_args.project is None:
+            for p in self.app.client_manager.identity.projects.list():
+                project_ids.append(getattr(p, 'id', ''))
+        else:
+            identity_client = self.app.client_manager.identity
+            project = utils.find_resource(
+                identity_client.projects,
+                parsed_args.project,
+            )
+            project_ids.append(getattr(project, 'id', ''))
 
         if parsed_args.compute:
             if parsed_args.detail:
diff --git a/openstackclient/tests/unit/common/test_quota.py b/openstackclient/tests/unit/common/test_quota.py
index bd59ca77fe..3fff062b4c 100644
--- a/openstackclient/tests/unit/common/test_quota.py
+++ b/openstackclient/tests/unit/common/test_quota.py
@@ -392,6 +392,29 @@ class TestQuotaList(TestQuota):
             parsed_args,
         )
 
+    def test_quota_list_compute_by_project(self):
+        # Two projects with non-default quotas
+        self.compute.quotas.get = mock.Mock(
+            side_effect=self.compute_quotas,
+        )
+
+        arglist = [
+            '--compute',
+            '--project', self.projects[0].name,
+        ]
+        verifylist = [
+            ('compute', True),
+            ('project', self.projects[0].name),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+        ret_quotas = list(data)
+
+        self.assertEqual(self.compute_column_header, columns)
+        self.assertEqual(self.compute_reference_data, ret_quotas[0])
+        self.assertEqual(1, len(ret_quotas))
+
     def test_quota_list_network(self):
         # Two projects with non-default quotas
         self.network.get_quota = mock.Mock(
@@ -461,6 +484,29 @@ class TestQuotaList(TestQuota):
         self.assertEqual(self.network_reference_data, ret_quotas[0])
         self.assertEqual(1, len(ret_quotas))
 
+    def test_quota_list_network_by_project(self):
+        # Two projects with non-default quotas
+        self.network.get_quota = mock.Mock(
+            side_effect=self.network_quotas,
+        )
+
+        arglist = [
+            '--network',
+            '--project', self.projects[0].name,
+        ]
+        verifylist = [
+            ('network', True),
+            ('project', self.projects[0].name),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+        ret_quotas = list(data)
+
+        self.assertEqual(self.network_column_header, columns)
+        self.assertEqual(self.network_reference_data, ret_quotas[0])
+        self.assertEqual(1, len(ret_quotas))
+
     def test_quota_list_volume(self):
         # Two projects with non-default quotas
         self.volume.quotas.get = mock.Mock(
@@ -530,6 +576,29 @@ class TestQuotaList(TestQuota):
         self.assertEqual(self.volume_reference_data, ret_quotas[0])
         self.assertEqual(1, len(ret_quotas))
 
+    def test_quota_list_volume_by_project(self):
+        # Two projects with non-default quotas
+        self.volume.quotas.get = mock.Mock(
+            side_effect=self.volume_quotas,
+        )
+
+        arglist = [
+            '--volume',
+            '--project', self.projects[0].name,
+        ]
+        verifylist = [
+            ('volume', True),
+            ('project', self.projects[0].name),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+        ret_quotas = list(data)
+
+        self.assertEqual(self.volume_column_header, columns)
+        self.assertEqual(self.volume_reference_data, ret_quotas[0])
+        self.assertEqual(1, len(ret_quotas))
+
 
 class TestQuotaSet(TestQuota):