Extend Quota API to report usage statistics
Extend existing quota api to report a quota set. The quota set
will contain a set of resources and its corresponding reservation,
limits and in_use count for each tenant.
DocImpact:Documentation describing the new API as well as the new
information that it exposes.
APIImpact
Co-Authored-By: Prince Boateng<prince.a.owusu.boateng@intel.com>
Change-Id: Ief2a6a4d2d7085e2a9dcd901123bc4fe6ac7ca22
Related-bug: #1599488
diff --git a/neutron/tests/tempest/api/admin/test_quotas.py b/neutron/tests/tempest/api/admin/test_quotas.py
index 85aecb9..fe8f511 100644
--- a/neutron/tests/tempest/api/admin/test_quotas.py
+++ b/neutron/tests/tempest/api/admin/test_quotas.py
@@ -13,9 +13,11 @@
# License for the specific language governing permissions and limitations
# under the License.
+import six
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
+from tempest import test
from neutron.tests.tempest.api import base
from neutron.tests.tempest import config
@@ -58,6 +60,19 @@
except lib_exc.NotFound:
pass
+ def _create_network(self, project_id):
+ network = self.create_network(client=self.admin_client,
+ tenant_id=project_id)
+ self.addCleanup(self.admin_client.delete_network,
+ network['id'])
+ return network
+
+ def _create_port(self, **kwargs):
+ port = self.admin_client.create_port(**kwargs)['port']
+ self.addCleanup(self.admin_client.delete_port,
+ port['id'])
+ return port
+
class QuotasTest(QuotasTestBase):
"""Test the Neutron API of Quotas.
@@ -67,6 +82,7 @@
list quotas for tenants who have non-default quota values
show quotas for a specified tenant
+ show detail quotas for a specified tenant
update quotas for a specified tenant
reset quotas to default values for a specified tenant
@@ -108,3 +124,39 @@
non_default_quotas = self.admin_client.list_quotas()
for q in non_default_quotas['quotas']:
self.assertNotEqual(tenant_id, q['tenant_id'])
+
+ @decorators.idempotent_id('e974b5ba-090a-452c-a578-f9710151d9fc')
+ @decorators.attr(type='gate')
+ @test.requires_ext(extension="quota_details", service="network")
+ def test_detail_quotas(self):
+ tenant_id = self._create_tenant()['id']
+ new_quotas = {'network': {'used': 1, 'limit': 2, 'reserved': 0},
+ 'port': {'used': 1, 'limit': 2, 'reserved': 0}}
+
+ # update quota limit for tenant
+ new_quota = {'network': new_quotas['network']['limit'], 'port':
+ new_quotas['port']['limit']}
+ quota_set = self._setup_quotas(tenant_id, **new_quota)
+
+ # create test resources
+ network = self._create_network(tenant_id)
+ post_body = {"network_id": network['id'],
+ "tenant_id": tenant_id}
+ self._create_port(**post_body)
+
+ # confirm from extended API quotas were changed
+ # as requested for tenant
+ quota_set = self.admin_client.show_details_quota(tenant_id)
+ quota_set = quota_set['quota']
+ for key, value in six.iteritems(new_quotas):
+ self.assertEqual(new_quotas[key]['limit'],
+ quota_set[key]['limit'])
+ self.assertEqual(new_quotas[key]['reserved'],
+ quota_set[key]['reserved'])
+ self.assertEqual(new_quotas[key]['used'],
+ quota_set[key]['used'])
+
+ # validate 'default' action for old extension
+ quota_limit = self.admin_client.show_quotas(tenant_id)['quota']
+ for key, value in six.iteritems(new_quotas):
+ self.assertEqual(new_quotas[key]['limit'], quota_limit[key])
diff --git a/neutron/tests/tempest/api/base.py b/neutron/tests/tempest/api/base.py
index 84746fb..0ec71c3 100644
--- a/neutron/tests/tempest/api/base.py
+++ b/neutron/tests/tempest/api/base.py
@@ -217,11 +217,12 @@
pass
@classmethod
- def create_network(cls, network_name=None, **kwargs):
+ def create_network(cls, network_name=None, client=None, **kwargs):
"""Wrapper utility that returns a test network."""
network_name = network_name or data_utils.rand_name('test-network-')
- body = cls.client.create_network(name=network_name, **kwargs)
+ client = client or cls.client
+ body = client.create_network(name=network_name, **kwargs)
network = body['network']
cls.networks.append(network)
return network
diff --git a/neutron/tests/tempest/services/network/json/network_client.py b/neutron/tests/tempest/services/network/json/network_client.py
index 39f2c38..12cdf97 100644
--- a/neutron/tests/tempest/services/network/json/network_client.py
+++ b/neutron/tests/tempest/services/network/json/network_client.py
@@ -124,7 +124,13 @@
# list of field's name. An example:
# {'fields': ['id', 'name']}
plural = self.pluralize(resource_name)
- uri = '%s/%s' % (self.get_uri(plural), resource_id)
+ if 'details_quotas' in plural:
+ details, plural = plural.split('_')
+ uri = '%s/%s/%s' % (self.get_uri(plural),
+ resource_id, details)
+ else:
+ uri = '%s/%s' % (self.get_uri(plural), resource_id)
+
if fields:
uri += '?' + urlparse.urlencode(fields, doseq=1)
resp, body = self.get(uri)