Add InstanceGroupList.get_counts()

This adds a method for getting counts of server groups in the database
for checking quota.

Part of blueprint cells-count-resources-to-check-quota-in-api

Change-Id: I9eadf93b432630607069cdf8ec1915920e32b905
This commit is contained in:
melanie witt 2017-03-30 17:15:02 +00:00
parent e78c923410
commit a196804834
3 changed files with 50 additions and 2 deletions

View File

@ -475,7 +475,8 @@ class InstanceGroupList(base.ObjectListBase, base.NovaObject):
# Version 1.5: InstanceGroup <= version 1.8
# Version 1.6: InstanceGroup <= version 1.9
# Version 1.7: InstanceGroup <= version 1.10
VERSION = '1.7'
# Version 1.8: Added get_counts() for quotas
VERSION = '1.8'
fields = {
'objects': fields.ListOfObjectsField('InstanceGroup'),
@ -496,6 +497,18 @@ class InstanceGroupList(base.ObjectListBase, base.NovaObject):
return base.obj_make_list(context, cls(context), objects.InstanceGroup,
main_db_groups)
@staticmethod
@db_api.api_context_manager.reader
def _get_counts_from_db(context, project_id, user_id=None):
query = context.session.query(api_models.InstanceGroup.id).\
filter_by(project_id=project_id)
counts = {}
counts['project'] = {'server_groups': query.count()}
if user_id:
query = query.filter_by(user_id=user_id)
counts['user'] = {'server_groups': query.count()}
return counts
@base.remotable_classmethod
def get_by_project_id(cls, context, project_id):
api_db_groups = cls._get_from_db(context, project_id=project_id)
@ -511,6 +524,21 @@ class InstanceGroupList(base.ObjectListBase, base.NovaObject):
return base.obj_make_list(context, cls(context), objects.InstanceGroup,
api_db_groups + main_db_groups)
@base.remotable_classmethod
def get_counts(cls, context, project_id, user_id=None):
"""Get the counts of InstanceGroup objects in the database.
:param context: The request context for database access
:param project_id: The project_id to count across
:param user_id: The user_id to count across
:returns: A dict containing the project-scoped counts and user-scoped
counts if user_id is specified. For example:
{'project': {'server_groups': <count across project>},
'user': {'server_groups': <count across user>}}
"""
return cls._get_counts_from_db(context, project_id, user_id=user_id)
@db_api.pick_context_manager_reader
def _get_main_instance_groups(context, limit):

View File

@ -185,6 +185,26 @@ class InstanceGroupObjectTestCase(test.TestCase):
self.assertTrue(base.obj_equal_prims(create_group, get_groups[0]))
ovo_fixture.compare_obj(self, get_groups[1], db_group)
def test_get_counts(self):
# _api_group() creates a group with project_id and user_id from
# self.context by default
self._api_group()
self._api_group(project_id='foo')
self._api_group(user_id='bar')
# Count only across a project
counts = objects.InstanceGroupList.get_counts(self.context, 'foo')
self.assertEqual(1, counts['project']['server_groups'])
self.assertNotIn('user', counts)
# Count across a project and a user
counts = objects.InstanceGroupList.get_counts(
self.context, self.context.project_id,
user_id=self.context.user_id)
self.assertEqual(2, counts['project']['server_groups'])
self.assertEqual(1, counts['user']['server_groups'])
def test_migrate_instance_groups(self):
self._api_group(name='apigroup')
orig_main_models = []

View File

@ -1110,7 +1110,7 @@ object_data = {
'InstanceFault': '1.2-7ef01f16f1084ad1304a513d6d410a38',
'InstanceFaultList': '1.2-6bb72de2872fe49ded5eb937a93f2451',
'InstanceGroup': '1.10-1a0c8c7447dc7ecb9da53849430c4a5f',
'InstanceGroupList': '1.7-be18078220513316abd0ae1b2d916873',
'InstanceGroupList': '1.8-90f8f1a445552bb3bbc9fa1ae7da27d4',
'InstanceInfoCache': '1.5-cd8b96fefe0fc8d4d337243ba0bf0e1e',
'InstanceList': '2.2-ff71772c7bf6d72f6ef6eee0199fb1c9',
'InstanceMapping': '1.0-65de80c491f54d19374703c0753c4d47',