Enhancing Quota-show feature in kingbird.
Quota show feature will display the updated quota values. This feature is enhanced by displaying the default quota values as well as updated values as in. The size of the resource column in database is increased for better usage. Change-Id: I814bd45a634342104c190f4437cae265ea3bb0f1 Closes-Bug:1740823 Closes-Bug:1742906
This commit is contained in:
parent
a6117883a6
commit
a8a562554e
@ -24,6 +24,7 @@ from pecan import request
|
|||||||
|
|
||||||
from kingbird.api.controllers import restcomm
|
from kingbird.api.controllers import restcomm
|
||||||
from kingbird.api import enforcer as enf
|
from kingbird.api import enforcer as enf
|
||||||
|
from kingbird.common import consts
|
||||||
from kingbird.common import exceptions
|
from kingbird.common import exceptions
|
||||||
from kingbird.common.i18n import _
|
from kingbird.common.i18n import _
|
||||||
from kingbird.common import utils
|
from kingbird.common import utils
|
||||||
@ -52,11 +53,26 @@ class BaseController(object):
|
|||||||
|
|
||||||
It references all other resources belonging to both the API's.
|
It references all other resources belonging to both the API's.
|
||||||
"""
|
"""
|
||||||
|
supported_quotas = list()
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(BaseController, self).__init__(*args, **kwargs)
|
super(BaseController, self).__init__(*args, **kwargs)
|
||||||
|
self.supported_quotas = list(
|
||||||
|
consts.CINDER_QUOTA_FIELDS +
|
||||||
|
consts.NEUTRON_QUOTA_FIELDS +
|
||||||
|
consts.NOVA_QUOTA_FIELDS)
|
||||||
self.rpc_client = rpc_client.EngineClient()
|
self.rpc_client = rpc_client.EngineClient()
|
||||||
|
|
||||||
|
def _format_quota_set(self, context, quota_set):
|
||||||
|
result = self.get_defaults(context,
|
||||||
|
CONF.kingbird_global_limit)
|
||||||
|
|
||||||
|
for quota in self.supported_quotas:
|
||||||
|
if quota in quota_set:
|
||||||
|
result[quota] = quota_set[quota]
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
def get_quota(self, context, project_id, action=None):
|
def get_quota(self, context, project_id, action=None):
|
||||||
"""Get quota for a specified tenant.
|
"""Get quota for a specified tenant.
|
||||||
|
|
||||||
@ -84,7 +100,8 @@ class BaseController(object):
|
|||||||
context, project_id)
|
context, project_id)
|
||||||
else:
|
else:
|
||||||
# Get quota limits for all the resources for a project
|
# Get quota limits for all the resources for a project
|
||||||
result = db_api.quota_get_all_by_project(context, project_id)
|
values = db_api.quota_get_all_by_project(context, project_id)
|
||||||
|
result = self._format_quota_set(context, values)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_defaults(self, context, config_defaults):
|
def get_defaults(self, context, config_defaults):
|
||||||
|
@ -48,7 +48,7 @@ def upgrade(migrate_engine):
|
|||||||
primary_key=True),
|
primary_key=True),
|
||||||
sqlalchemy.Column('target_region', sqlalchemy.String(36),
|
sqlalchemy.Column('target_region', sqlalchemy.String(36),
|
||||||
primary_key=True),
|
primary_key=True),
|
||||||
sqlalchemy.Column('resource', sqlalchemy.String(36),
|
sqlalchemy.Column('resource', sqlalchemy.String(255),
|
||||||
primary_key=True),
|
primary_key=True),
|
||||||
sqlalchemy.Column('resource_type', sqlalchemy.String(36),
|
sqlalchemy.Column('resource_type', sqlalchemy.String(36),
|
||||||
nullable=False),
|
nullable=False),
|
||||||
|
@ -180,7 +180,7 @@ class ResourceSync(BASE, KingbirdBase):
|
|||||||
|
|
||||||
target_region = Column('target_region', String(36), primary_key=True)
|
target_region = Column('target_region', String(36), primary_key=True)
|
||||||
|
|
||||||
resource = Column('resource', String(36), primary_key=True)
|
resource = Column('resource', String(255), primary_key=True)
|
||||||
|
|
||||||
resource_type = Column('resource_type', String(36), nullable=False)
|
resource_type = Column('resource_type', String(36), nullable=False)
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ from oslo_config import cfg
|
|||||||
from kingbird.api.controllers.v1 import quota_manager
|
from kingbird.api.controllers.v1 import quota_manager
|
||||||
from kingbird.common import config
|
from kingbird.common import config
|
||||||
from kingbird.rpc import client as rpc_client
|
from kingbird.rpc import client as rpc_client
|
||||||
|
from kingbird.tests.tempest.scenario import consts as tempest_consts
|
||||||
from kingbird.tests.unit.api import test_root_controller as testroot
|
from kingbird.tests.unit.api import test_root_controller as testroot
|
||||||
from kingbird.tests import utils
|
from kingbird.tests import utils
|
||||||
|
|
||||||
@ -51,19 +52,47 @@ class TestQuotaManager(testroot.KBApiTest):
|
|||||||
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
||||||
@mock.patch.object(quota_manager, 'db_api')
|
@mock.patch.object(quota_manager, 'db_api')
|
||||||
def test_get_all_admin(self, mock_db_api):
|
def test_get_all_admin(self, mock_db_api):
|
||||||
Res = Result(TARGET_FAKE_TENANT, 'ram', 100)
|
updated_values = {'subnet': 11}
|
||||||
mock_db_api.quota_get_all_by_project.return_value = \
|
default_values = tempest_consts.DEFAULT_QUOTAS
|
||||||
{"project_id": Res.project_id,
|
|
||||||
Res.resource: Res.hard_limit}
|
|
||||||
fake_url = '/v1.0/%s/os-quota-sets/%s'\
|
fake_url = '/v1.0/%s/os-quota-sets/%s'\
|
||||||
% (FAKE_TENANT, TARGET_FAKE_TENANT)
|
% (FAKE_TENANT, FAKE_TENANT)
|
||||||
|
mock_db_api.quota_get_all_by_project.return_value = updated_values
|
||||||
|
mock_db_api.quota_class_get_default.return_value = default_values
|
||||||
response = self.app.get(
|
response = self.app.get(
|
||||||
fake_url,
|
fake_url,
|
||||||
headers=ADMIN_HEADERS)
|
headers=ADMIN_HEADERS)
|
||||||
self.assertEqual(response.status_int, 200)
|
default_values.update(updated_values)
|
||||||
self.assertEqual({'quota_set':
|
self.assertEqual(response.json['quota_set'], default_values)
|
||||||
{'project_id': TARGET_FAKE_TENANT, 'ram': 100}},
|
|
||||||
eval(response.text))
|
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
||||||
|
@mock.patch.object(quota_manager, 'db_api')
|
||||||
|
def test_get_tenant_with_admin(self, mock_db_api):
|
||||||
|
updated_values = {'subnet': 11}
|
||||||
|
default_values = tempest_consts.DEFAULT_QUOTAS
|
||||||
|
fake_url = '/v1.0/%s/os-quota-sets/%s'\
|
||||||
|
% (FAKE_TENANT, TARGET_FAKE_TENANT)
|
||||||
|
mock_db_api.quota_get_all_by_project.return_value = updated_values
|
||||||
|
mock_db_api.quota_class_get_default.return_value = default_values
|
||||||
|
response = self.app.get(
|
||||||
|
fake_url,
|
||||||
|
headers=ADMIN_HEADERS)
|
||||||
|
default_values.update(updated_values)
|
||||||
|
self.assertEqual(response.json['quota_set'], default_values)
|
||||||
|
|
||||||
|
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
||||||
|
@mock.patch.object(quota_manager, 'db_api')
|
||||||
|
def test_get_tenant_without_admin(self, mock_db_api):
|
||||||
|
updated_values = {'subnet': 11}
|
||||||
|
default_values = tempest_consts.DEFAULT_QUOTAS
|
||||||
|
fake_url = '/v1.0/%s/os-quota-sets/%s'\
|
||||||
|
% (TARGET_FAKE_TENANT, TARGET_FAKE_TENANT)
|
||||||
|
mock_db_api.quota_get_all_by_project.return_value = updated_values
|
||||||
|
mock_db_api.quota_class_get_default.return_value = default_values
|
||||||
|
response = self.app.get(
|
||||||
|
fake_url,
|
||||||
|
headers=NON_ADMIN_HEADERS)
|
||||||
|
default_values.update(updated_values)
|
||||||
|
self.assertEqual(response.json['quota_set'], default_values)
|
||||||
|
|
||||||
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
||||||
@mock.patch.object(quota_manager, 'db_api')
|
@mock.patch.object(quota_manager, 'db_api')
|
||||||
@ -268,22 +297,6 @@ class TestQuotaManager(testroot.KBApiTest):
|
|||||||
self.app.get, fake_url,
|
self.app.get, fake_url,
|
||||||
headers=NON_ADMIN_HEADERS)
|
headers=NON_ADMIN_HEADERS)
|
||||||
|
|
||||||
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
|
||||||
@mock.patch.object(quota_manager, 'db_api')
|
|
||||||
def test_get_all_another_tenant_with_admin(self, mock_db_api):
|
|
||||||
fake_url = '/v1.0/%s/os-quota-sets/%s'\
|
|
||||||
% (FAKE_TENANT, TARGET_FAKE_TENANT)
|
|
||||||
Res = Result('tenant_1', 'ram', 100)
|
|
||||||
mock_db_api.quota_get_all_by_project.return_value = \
|
|
||||||
{"project_id": Res.project_id,
|
|
||||||
Res.resource: Res.hard_limit}
|
|
||||||
response = self.app.get(
|
|
||||||
fake_url,
|
|
||||||
headers=ADMIN_HEADERS)
|
|
||||||
self.assertEqual(response.status_int, 200)
|
|
||||||
self.assertEqual({'quota_set': {'project_id': 'tenant_1', 'ram': 100}},
|
|
||||||
eval(response.text))
|
|
||||||
|
|
||||||
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
||||||
@mock.patch.object(quota_manager, 'db_api')
|
@mock.patch.object(quota_manager, 'db_api')
|
||||||
def test_get_usages_another_tenant_no_admin(self, mock_db_api):
|
def test_get_usages_another_tenant_no_admin(self, mock_db_api):
|
||||||
|
@ -21,6 +21,7 @@ from oslo_config import cfg
|
|||||||
from kingbird.api.controllers.v1 import quota_manager
|
from kingbird.api.controllers.v1 import quota_manager
|
||||||
from kingbird.common import config
|
from kingbird.common import config
|
||||||
from kingbird.rpc import client as rpc_client
|
from kingbird.rpc import client as rpc_client
|
||||||
|
from kingbird.tests.tempest.scenario import consts as tempest_consts
|
||||||
from kingbird.tests.unit.api import test_root_controller as testroot
|
from kingbird.tests.unit.api import test_root_controller as testroot
|
||||||
from kingbird.tests import utils
|
from kingbird.tests import utils
|
||||||
|
|
||||||
@ -49,21 +50,18 @@ class TestQuotaManager(testroot.KBApiTest):
|
|||||||
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
||||||
@mock.patch.object(quota_manager, 'db_api')
|
@mock.patch.object(quota_manager, 'db_api')
|
||||||
@mock.patch.object(quota_manager, 'enf')
|
@mock.patch.object(quota_manager, 'enf')
|
||||||
def test_get_quota_details_admin(self, mock_enf, mock_db_api):
|
def test_get_quota_details(self, mock_enf, mock_db_api):
|
||||||
Res = Result(TARGET_FAKE_TENANT, 'ram', 100)
|
updated_values = {'subnet': 11}
|
||||||
mock_enf.enforce.return_value = True
|
default_values = tempest_consts.DEFAULT_QUOTAS
|
||||||
mock_db_api.quota_get_all_by_project.return_value = \
|
|
||||||
{"project_id": Res.project_id,
|
|
||||||
Res.resource: Res.hard_limit}
|
|
||||||
fake_url = '/v1.1/%s/os-quota-sets/'\
|
fake_url = '/v1.1/%s/os-quota-sets/'\
|
||||||
% (FAKE_TENANT)
|
% (FAKE_TENANT)
|
||||||
|
mock_db_api.quota_get_all_by_project.return_value = updated_values
|
||||||
|
mock_db_api.quota_class_get_default.return_value = default_values
|
||||||
response = self.app.get(
|
response = self.app.get(
|
||||||
fake_url,
|
fake_url,
|
||||||
headers=HEADERS)
|
headers=HEADERS)
|
||||||
self.assertEqual(response.status_int, 200)
|
default_values.update(updated_values)
|
||||||
self.assertEqual({'quota_set':
|
self.assertEqual(response.json['quota_set'], default_values)
|
||||||
{'project_id': TARGET_FAKE_TENANT, 'ram': 100}},
|
|
||||||
eval(response.text))
|
|
||||||
|
|
||||||
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
||||||
@mock.patch.object(quota_manager, 'db_api')
|
@mock.patch.object(quota_manager, 'db_api')
|
||||||
@ -259,25 +257,6 @@ class TestQuotaManager(testroot.KBApiTest):
|
|||||||
self.app.get, fake_url,
|
self.app.get, fake_url,
|
||||||
headers=HEADERS)
|
headers=HEADERS)
|
||||||
|
|
||||||
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
|
||||||
@mock.patch.object(quota_manager, 'db_api')
|
|
||||||
@mock.patch.object(quota_manager, 'enf')
|
|
||||||
def test_get_complete_quota_another_tenant_with_admin(self, mock_enf,
|
|
||||||
mock_db_api):
|
|
||||||
fake_url = '/v1.1/%s/os-quota-sets'\
|
|
||||||
% (FAKE_TENANT)
|
|
||||||
Res = Result(FAKE_TENANT, 'ram', 100)
|
|
||||||
mock_db_api.quota_get_all_by_project.return_value = \
|
|
||||||
{"project_id": Res.project_id,
|
|
||||||
Res.resource: Res.hard_limit}
|
|
||||||
mock_enf.enforce.return_value = True
|
|
||||||
response = self.app.get(
|
|
||||||
fake_url,
|
|
||||||
headers=HEADERS)
|
|
||||||
self.assertEqual(response.status_int, 200)
|
|
||||||
self.assertEqual({'quota_set': {'project_id': FAKE_TENANT,
|
|
||||||
'ram': 100}}, eval(response.text))
|
|
||||||
|
|
||||||
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
@mock.patch.object(rpc_client, 'EngineClient', new=mock.Mock())
|
||||||
@mock.patch.object(quota_manager, 'enf')
|
@mock.patch.object(quota_manager, 'enf')
|
||||||
def test_get_usages_another_tenant_non_admin(self, mock_enf):
|
def test_get_usages_another_tenant_non_admin(self, mock_enf):
|
||||||
|
Loading…
Reference in New Issue
Block a user