Add CellMapping.get_by_project_id() query method

This allows us to query for CellMapping objects by providing a project_id.
We get back a list of cells for which the project has InstanceMappings.

Change-Id: I40b866dcba5f3665eb40011afe65638184aae9c6
This commit is contained in:
Dan Smith 2017-10-02 12:22:38 -07:00
parent a8d3c61a57
commit a084a103b8
2 changed files with 65 additions and 0 deletions

View File

@ -11,6 +11,7 @@
# under the License.
from oslo_utils import versionutils
from sqlalchemy.orm import joinedload
from sqlalchemy.sql.expression import asc
from sqlalchemy.sql import false
from sqlalchemy.sql import true
@ -165,3 +166,22 @@ class CellMappingList(base.ObjectListBase, base.NovaObject):
def get_by_disabled(cls, context, disabled):
db_mappings = cls._get_by_disabled_from_db(context, disabled)
return base.obj_make_list(context, cls(), CellMapping, db_mappings)
@staticmethod
@db_api.api_context_manager.reader
def _get_by_project_id_from_db(context, project_id):
mappings = context.session.query(
api_models.InstanceMapping).\
filter_by(project_id=project_id).\
group_by(api_models.InstanceMapping.cell_id).\
options(joinedload('cell_mapping', innerjoin=True)).\
all()
return (mapping.cell_mapping for mapping in mappings)
@classmethod
def get_by_project_id(cls, context, project_id):
"""Return a list of CellMapping objects which correspond to cells in
which project_id has InstanceMappings.
"""
db_mappings = cls._get_by_project_id_from_db(context, project_id)
return base.obj_make_list(context, cls(), CellMapping, db_mappings)

View File

@ -14,6 +14,7 @@ from oslo_utils import uuidutils
from nova import context
from nova import exception
from nova import objects
from nova.objects import cell_mapping
from nova import test
from nova.tests import fixtures
@ -118,3 +119,47 @@ class CellMappingListTestCase(test.NoDBTestCase):
disabled=True)
self.assertEqual(1, len(mappings))
self.assertEqual(disabled_mapping['uuid'], mappings[0].uuid)
def test_get_by_project_id(self):
ctxt = context.RequestContext()
cell1 = objects.CellMapping.get_by_uuid(ctxt, create_mapping().uuid)
cell2 = objects.CellMapping.get_by_uuid(ctxt, create_mapping().uuid)
cell3 = objects.CellMapping.get_by_uuid(ctxt, create_mapping().uuid)
cells = [cell1, cell2, cell3]
# Proj1 is all in one cell
for i in range(0, 5):
uuid = uuidutils.generate_uuid()
im = objects.InstanceMapping(context=ctxt,
instance_uuid=uuid,
cell_mapping=cell1,
project_id='proj1')
im.create()
# Proj2 is in the first two cells
for i in range(0, 5):
uuid = uuidutils.generate_uuid()
cell = cells[i % 2]
im = objects.InstanceMapping(context=ctxt,
instance_uuid=uuid,
cell_mapping=cell,
project_id='proj2')
im.create()
# One mapping has no cell because it's a BuildRequest
im = objects.InstanceMapping(context=ctxt,
instance_uuid=uuidutils.generate_uuid(),
cell_mapping=None,
project_id='proj2')
im.create()
# Proj1 should only be in cell1 and we should only get back
# a single mapping for it
cells = objects.CellMappingList.get_by_project_id(ctxt, 'proj1')
self.assertEqual(1, len(cells))
self.assertEqual(cell1.uuid, cells[0].uuid)
cells = objects.CellMappingList.get_by_project_id(ctxt, 'proj2')
self.assertEqual(2, len(cells))
self.assertEqual(sorted([cell1.uuid, cell2.uuid]),
sorted([cm.uuid for cm in cells]))