Make quotas respect instance_list_per_project_cells

This option was introduced in order to limit queries to cells which only
belong to the project we're interacting with.  However, The nova quota
code was not respecting it and therefore it was always trying to get the
cells assigned to a project even with that option disabled.

This patch makes the quota code respect that option and adds testing to
ensure that enabling the option does make sure it doesn't search all
cells but only the ones for this project.

Closes-Bug: #1878979

 Conflicts:
    nova/tests/functional/db/test_quota.py

NOTE(melwitt): The conflict and difference (import mock) from the
cherry-picked change are because of the following changes not in Stein:

  Iaffb27bd8c562ba120047c04bb62619c0864f594
  I3ff39d5ed99a68ad8678e5ff62b343f3018b4768

Change-Id: I2e0d48e799e70d550f912ad8a424c86df3ade3a2
(cherry picked from commit ab16946885)
(cherry picked from commit fa2bfac862)
(cherry picked from commit 91160c4238)
This commit is contained in:
Mohammed Naser 2020-05-15 16:49:12 -04:00 committed by melanie witt
parent a63c97fd2d
commit 4413e9bf56
2 changed files with 24 additions and 5 deletions

View File

@ -1147,8 +1147,12 @@ def _instances_cores_ram_count(context, project_id, user_id=None):
# this filtering if there is more than one non-cell0 cell.
# TODO(tssurya): Consider adding a scatter_gather_cells_for_project
# variant that makes this native to nova.context.
cell_mappings = objects.CellMappingList.get_by_project_id(
context, project_id)
if CONF.api.instance_list_per_project_cells:
cell_mappings = objects.CellMappingList.get_by_project_id(
context, project_id)
else:
nova_context.load_cells()
cell_mappings = nova_context.CELLS
results = nova_context.scatter_gather_cells(
context, cell_mappings, nova_context.CELL_TIMEOUT,
objects.InstanceList.get_counts, project_id, user_id=user_id)

View File

@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import mock
from oslo_utils import uuidutils
from nova import context
@ -78,7 +79,9 @@ class QuotaTestCase(test.NoDBTestCase):
self.assertEqual(2, count['user']['server_group_members'])
def test_instances_cores_ram_count(self):
@mock.patch('nova.objects.CellMappingList.get_by_project_id',
wraps=objects.CellMappingList.get_by_project_id)
def test_instances_cores_ram_count(self, mock_get_project_cell_mappings):
ctxt = context.RequestContext('fake-user', 'fake-project')
mapping1 = objects.CellMapping(context=ctxt,
uuid=uuidutils.generate_uuid(),
@ -136,10 +139,22 @@ class QuotaTestCase(test.NoDBTestCase):
project_id='fake-project')
im.create()
# Count instances, cores, and ram across cells
# Count instances, cores, and ram across cells (all cells)
count = quota._instances_cores_ram_count(ctxt, 'fake-project',
user_id='fake-user')
mock_get_project_cell_mappings.assert_not_called()
self.assertEqual(3, count['project']['instances'])
self.assertEqual(10, count['project']['cores'])
self.assertEqual(2560, count['project']['ram'])
self.assertEqual(2, count['user']['instances'])
self.assertEqual(6, count['user']['cores'])
self.assertEqual(1536, count['user']['ram'])
# Count instances, cores, and ram across cells (query cell subset)
self.flags(instance_list_per_project_cells=True, group='api')
count = quota._instances_cores_ram_count(ctxt, 'fake-project',
user_id='fake-user')
mock_get_project_cell_mappings.assert_called_with(ctxt, 'fake-project')
self.assertEqual(3, count['project']['instances'])
self.assertEqual(10, count['project']['cores'])
self.assertEqual(2560, count['project']['ram'])