summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorSindhu Devale <sindhu.devale@intel.com>2016-09-29 15:32:51 -0500
committerSindhu Devale <sindhu.devale@intel.com>2017-03-10 14:59:47 +0000
commit58591d3c37c0265d8775f881271ba4d987e5ffb6 (patch)
tree493ebc94d0f711e2dc1150a8ed28ba713c4612c2 /openstackclient
parent35c308ebadc23929f96eb74ab59091b7e691f09e (diff)
downloadpython-openstackclient-58591d3c37c0265d8775f881271ba4d987e5ffb6.tar.gz
OSC Quota List
Implement Neutron feature of Quota List into OpenStack Client. Change-Id: Idf941acf8d00b136776b7381b877c56d82622f57 Partially-Implements: blueprint neutron-client-quota
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/common/quota.py173
-rw-r--r--openstackclient/tests/functional/common/test_quota.py21
-rw-r--r--openstackclient/tests/unit/common/test_quota.py159
-rw-r--r--openstackclient/tests/unit/compute/v2/fakes.py64
-rw-r--r--openstackclient/tests/unit/network/v2/fakes.py50
-rw-r--r--openstackclient/tests/unit/volume/v2/fakes.py50
6 files changed, 517 insertions, 0 deletions
diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py
index afc6195f..b62d661c 100644
--- a/openstackclient/common/quota.py
+++ b/openstackclient/common/quota.py
@@ -16,6 +16,7 @@
"""Quota action implementations"""
import itertools
+import logging
import sys
from osc_lib.command import command
@@ -25,6 +26,8 @@ import six
from openstackclient.i18n import _
+LOG = logging.getLogger(__name__)
+
# List the quota items, map the internal argument name to the option
# name that the user sees.
@@ -78,6 +81,176 @@ NETWORK_QUOTAS = {
'l7policy': 'l7policies',
}
+NETWORK_KEYS = ['floating_ips', 'networks', 'rbac_policies', 'routers',
+ 'ports', 'security_group_rules', 'security_groups',
+ 'subnet_pools', 'subnets']
+
+
+def _xform_get_quota(data, value, keys):
+ res = []
+ res_info = {}
+ for key in keys:
+ res_info[key] = getattr(data, key, '')
+
+ res_info['id'] = value
+ res.append(res_info)
+ return res
+
+
+class ListQuota(command.Lister):
+ _description = _("List quotas for all projects "
+ "with non-default quota values")
+
+ def get_parser(self, prog_name):
+ parser = super(ListQuota, self).get_parser(prog_name)
+ option = parser.add_mutually_exclusive_group(required=True)
+ option.add_argument(
+ '--compute',
+ action='store_true',
+ default=False,
+ help=_('List compute quota'),
+ )
+ option.add_argument(
+ '--volume',
+ action='store_true',
+ default=False,
+ help=_('List volume quota'),
+ )
+ option.add_argument(
+ '--network',
+ action='store_true',
+ default=False,
+ help=_('List network quota'),
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ projects = self.app.client_manager.identity.projects.list()
+ result = []
+ project_ids = [getattr(p, 'id', '') for p in projects]
+
+ if parsed_args.compute:
+ compute_client = self.app.client_manager.compute
+ for p in project_ids:
+ data = compute_client.quotas.get(p)
+ result_data = _xform_get_quota(data, p,
+ COMPUTE_QUOTAS.keys())
+ default_data = compute_client.quotas.defaults(p)
+ result_default = _xform_get_quota(default_data,
+ p,
+ COMPUTE_QUOTAS.keys())
+ if result_default != result_data:
+ result += result_data
+
+ columns = (
+ 'id',
+ 'cores',
+ 'fixed_ips',
+ 'injected_files',
+ 'injected_file_content_bytes',
+ 'injected_file_path_bytes',
+ 'instances',
+ 'key_pairs',
+ 'metadata_items',
+ 'ram',
+ 'server_groups',
+ 'server_group_members',
+ )
+ column_headers = (
+ 'Project ID',
+ 'Cores',
+ 'Fixed IPs',
+ 'Injected Files',
+ 'Injected File Content Bytes',
+ 'Injected File Path Bytes',
+ 'Instances',
+ 'Key Pairs',
+ 'Metadata Items',
+ 'Ram',
+ 'Server Groups',
+ 'Server Group Members',
+ )
+ return (column_headers,
+ (utils.get_dict_properties(
+ s, columns,
+ ) for s in result))
+ if parsed_args.volume:
+ volume_client = self.app.client_manager.volume
+ for p in project_ids:
+ data = volume_client.quotas.get(p)
+ result_data = _xform_get_quota(data, p,
+ VOLUME_QUOTAS.keys())
+ default_data = volume_client.quotas.defaults(p)
+ result_default = _xform_get_quota(default_data,
+ p,
+ VOLUME_QUOTAS.keys())
+ if result_default != result_data:
+ result += result_data
+
+ columns = (
+ 'id',
+ 'backups',
+ 'backup_gigabytes',
+ 'gigabytes',
+ 'per_volume_gigabytes',
+ 'snapshots',
+ 'volumes',
+ )
+ column_headers = (
+ 'Project ID',
+ 'Backups',
+ 'Backup Gigabytes',
+ 'Gigabytes',
+ 'Per Volume Gigabytes',
+ 'Snapshots',
+ 'Volumes',
+ )
+ return (column_headers,
+ (utils.get_dict_properties(
+ s, columns,
+ ) for s in result))
+ if parsed_args.network:
+ client = self.app.client_manager.network
+ for p in project_ids:
+ data = client.get_quota(p)
+ result_data = _xform_get_quota(data, p, NETWORK_KEYS)
+ default_data = client.get_quota_default(p)
+ result_default = _xform_get_quota(default_data,
+ p, NETWORK_KEYS)
+ if result_default != result_data:
+ result += result_data
+
+ columns = (
+ 'id',
+ 'floating_ips',
+ 'networks',
+ 'ports',
+ 'rbac_policies',
+ 'routers',
+ 'security_groups',
+ 'security_group_rules',
+ 'subnets',
+ 'subnet_pools',
+ )
+ column_headers = (
+ 'Project ID',
+ 'Floating IPs',
+ 'Networks',
+ 'Ports',
+ 'RBAC Policies',
+ 'Routers',
+ 'Security Groups',
+ 'Security Group Rules',
+ 'Subnets',
+ 'Subnet Pools'
+ )
+ return (column_headers,
+ (utils.get_dict_properties(
+ s, columns,
+ ) for s in result))
+
+ return ((), ())
+
class SetQuota(command.Command):
_description = _("Set quotas for project or class")
diff --git a/openstackclient/tests/functional/common/test_quota.py b/openstackclient/tests/functional/common/test_quota.py
index c1de9aa9..8092b3ce 100644
--- a/openstackclient/tests/functional/common/test_quota.py
+++ b/openstackclient/tests/functional/common/test_quota.py
@@ -25,6 +25,27 @@ class QuotaTests(base.TestCase):
cls.PROJECT_NAME =\
cls.get_openstack_configuration_value('auth.project_name')
+ def test_quota_list_network_option(self):
+ self.openstack('quota set --networks 40 ' +
+ self.PROJECT_NAME)
+ raw_output = self.openstack('quota list --network')
+ self.assertIsNotNone(raw_output)
+ self.assertIn("40", raw_output)
+
+ def test_quota_list_compute_option(self):
+ self.openstack('quota set --instances 40 ' +
+ self.PROJECT_NAME)
+ raw_output = self.openstack('quota list --compute')
+ self.assertIsNotNone(raw_output)
+ self.assertIn("40", raw_output)
+
+ def test_quota_list_volume_option(self):
+ self.openstack('quota set --backups 40 ' +
+ self.PROJECT_NAME)
+ raw_output = self.openstack('quota list --volume')
+ self.assertIsNotNone(raw_output)
+ self.assertIn("40", raw_output)
+
def test_quota_set(self):
self.openstack('quota set --instances 11 --volumes 11 --networks 11 ' +
self.PROJECT_NAME)
diff --git a/openstackclient/tests/unit/common/test_quota.py b/openstackclient/tests/unit/common/test_quota.py
index 244d74d2..306615bd 100644
--- a/openstackclient/tests/unit/common/test_quota.py
+++ b/openstackclient/tests/unit/common/test_quota.py
@@ -19,6 +19,7 @@ from openstackclient.common import quota
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
from openstackclient.tests.unit import fakes
from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
+from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes_v3
from openstackclient.tests.unit.network.v2 import fakes as network_fakes
from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
@@ -530,3 +531,161 @@ class TestQuotaShow(TestQuota):
self.network.get_quota.assert_called_once_with(
identity_fakes.project_id)
self.assertNotCalled(self.network.get_quota_default)
+
+
+class TestQuotaList(TestQuota):
+ """Test cases for quota list command"""
+
+ project = identity_fakes_v3.FakeProject.create_one_project()
+
+ quota_list = network_fakes.FakeQuota.create_one_net_quota()
+ quota_list1 = compute_fakes.FakeQuota.create_one_comp_quota()
+ quota_list2 = volume_fakes.FakeQuota.create_one_vol_quota()
+
+ default_quota = network_fakes.FakeQuota.create_one_default_net_quota()
+ default_quota1 = compute_fakes.FakeQuota.create_one_default_comp_quota()
+ default_quota2 = volume_fakes.FakeQuota.create_one_default_vol_quota()
+
+ reference_data = (project.id,
+ quota_list.floating_ips,
+ quota_list.networks,
+ quota_list.ports,
+ quota_list.rbac_policies,
+ quota_list.routers,
+ quota_list.security_groups,
+ quota_list.security_group_rules,
+ quota_list.subnets,
+ quota_list.subnet_pools)
+
+ comp_reference_data = (project.id,
+ quota_list1.cores,
+ quota_list1.fixed_ips,
+ quota_list1.injected_files,
+ quota_list1.injected_file_content_bytes,
+ quota_list1.injected_file_path_bytes,
+ quota_list1.instances,
+ quota_list1.key_pairs,
+ quota_list1.metadata_items,
+ quota_list1.ram,
+ quota_list1.server_groups,
+ quota_list1.server_group_members)
+
+ vol_reference_data = (project.id,
+ quota_list2.backups,
+ quota_list2.backup_gigabytes,
+ quota_list2.gigabytes,
+ quota_list2.per_volume_gigabytes,
+ quota_list2.snapshots,
+ quota_list2.volumes)
+
+ net_column_header = (
+ 'Project ID',
+ 'Floating IPs',
+ 'Networks',
+ 'Ports',
+ 'RBAC Policies',
+ 'Routers',
+ 'Security Groups',
+ 'Security Group Rules',
+ 'Subnets',
+ 'Subnet Pools'
+ )
+
+ comp_column_header = (
+ 'Project ID',
+ 'Cores',
+ 'Fixed IPs',
+ 'Injected Files',
+ 'Injected File Content Bytes',
+ 'Injected File Path Bytes',
+ 'Instances',
+ 'Key Pairs',
+ 'Metadata Items',
+ 'Ram',
+ 'Server Groups',
+ 'Server Group Members',
+ )
+
+ vol_column_header = (
+ 'Project ID',
+ 'Backups',
+ 'Backup Gigabytes',
+ 'Gigabytes',
+ 'Per Volume Gigabytes',
+ 'Snapshots',
+ 'Volumes',
+ )
+
+ def setUp(self):
+ super(TestQuotaList, self).setUp()
+
+ self.projects_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(identity_fakes.PROJECT),
+ loaded=True,
+ )
+
+ self.identity = self.app.client_manager.identity
+ self.identity.tenants.list = mock.Mock(return_value=[self.project])
+
+ self.network = self.app.client_manager.network
+ self.compute = self.app.client_manager.compute
+ self.volume = self.app.client_manager.volume
+
+ self.network.get_quota = mock.Mock(return_value=self.quota_list)
+ self.compute.quotas.get = mock.Mock(return_value=self.quota_list1)
+ self.volume.quotas.get = mock.Mock(return_value=self.quota_list2)
+
+ self.network.get_quota_default = mock.Mock(
+ return_value=self.default_quota)
+ self.compute.quotas.defaults = mock.Mock(
+ return_value=self.default_quota1)
+ self.volume.quotas.defaults = mock.Mock(
+ return_value=self.default_quota2)
+
+ self.cmd = quota.ListQuota(self.app, None)
+
+ def test_quota_list_network(self):
+ arglist = [
+ '--network'
+ ]
+ verifylist = [
+ ('network', True)
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.assertEqual(self.net_column_header, columns)
+
+ self.assertEqual(self.reference_data, list(data)[0])
+
+ def test_quota_list_compute(self):
+ arglist = [
+ '--compute'
+ ]
+ verifylist = [
+ ('compute', True)
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.assertEqual(self.comp_column_header, columns)
+
+ self.assertEqual(self.comp_reference_data, list(data)[0])
+
+ def test_quota_list_volume(self):
+ arglist = [
+ '--volume'
+ ]
+ verifylist = [
+ ('volume', True)
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.assertEqual(self.vol_column_header, columns)
+
+ self.assertEqual(self.vol_reference_data, list(data)[0])
diff --git a/openstackclient/tests/unit/compute/v2/fakes.py b/openstackclient/tests/unit/compute/v2/fakes.py
index 4fe735b6..63b98a2a 100644
--- a/openstackclient/tests/unit/compute/v2/fakes.py
+++ b/openstackclient/tests/unit/compute/v2/fakes.py
@@ -1313,3 +1313,67 @@ class FakeUsage(object):
usages.append(FakeUsage.create_one_usage(attrs))
return usages
+
+
+class FakeQuota(object):
+ """Fake quota"""
+
+ @staticmethod
+ def create_one_comp_quota(attrs=None):
+ """Create one quota"""
+
+ attrs = attrs or {}
+
+ quota_attrs = {
+ 'id': 'project-id-' + uuid.uuid4().hex,
+ 'cores': 20,
+ 'fixed_ips': 30,
+ 'injected_files': 100,
+ 'injected_file_content_bytes': 10240,
+ 'injected_file_path_bytes': 255,
+ 'instances': 50,
+ 'key_pairs': 20,
+ 'metadata_items': 10,
+ 'ram': 51200,
+ 'server_groups': 10,
+ 'server_group_members': 10
+ }
+
+ quota_attrs.update(attrs)
+ quota = fakes.FakeResource(
+ info=copy.deepcopy(quota_attrs),
+ loaded=True)
+
+ quota.project_id = quota_attrs['id']
+
+ return quota
+
+ @staticmethod
+ def create_one_default_comp_quota(attrs=None):
+ """Crate one quota"""
+
+ attrs = attrs or {}
+
+ quota_attrs = {
+ 'id': 'project-id-' + uuid.uuid4().hex,
+ 'cores': 10,
+ 'fixed_ips': 10,
+ 'injected_files': 100,
+ 'injected_file_content_bytes': 10240,
+ 'injected_file_path_bytes': 255,
+ 'instances': 20,
+ 'key_pairs': 20,
+ 'metadata_items': 10,
+ 'ram': 51200,
+ 'server_groups': 10,
+ 'server_group_members': 10
+ }
+
+ quota_attrs.update(attrs)
+ quota = fakes.FakeResource(
+ info=copy.deepcopy(quota_attrs),
+ loaded=True)
+
+ quota.project_id = quota_attrs['id']
+
+ return quota
diff --git a/openstackclient/tests/unit/network/v2/fakes.py b/openstackclient/tests/unit/network/v2/fakes.py
index dcecbeee..d8756688 100644
--- a/openstackclient/tests/unit/network/v2/fakes.py
+++ b/openstackclient/tests/unit/network/v2/fakes.py
@@ -1494,3 +1494,53 @@ class FakeNetworkServiceProvider(object):
create_one_network_service_provider(
attrs))
return service_providers
+
+
+class FakeQuota(object):
+ """Fake quota"""
+
+ @staticmethod
+ def create_one_net_quota(attrs=None):
+ """Create one quota"""
+ attrs = attrs or {}
+
+ quota_attrs = {
+ 'floating_ips': 20,
+ 'networks': 25,
+ 'ports': 11,
+ 'rbac_policies': 15,
+ 'routers': 40,
+ 'security_groups': 10,
+ 'security_group_rules': 100,
+ 'subnets': 20,
+ 'subnet_pools': 30}
+
+ quota_attrs.update(attrs)
+
+ quota = fakes.FakeResource(
+ info=copy.deepcopy(quota_attrs),
+ loaded=True)
+ return quota
+
+ @staticmethod
+ def create_one_default_net_quota(attrs=None):
+ """Create one quota"""
+ attrs = attrs or {}
+
+ quota_attrs = {
+ 'floatingip': 30,
+ 'network': 20,
+ 'port': 10,
+ 'rbac_policy': 25,
+ 'router': 30,
+ 'security_group': 30,
+ 'security_group_rule': 200,
+ 'subnet': 10,
+ 'subnetpool': 20}
+
+ quota_attrs.update(attrs)
+
+ quota = fakes.FakeResource(
+ info=copy.deepcopy(quota_attrs),
+ loaded=True)
+ return quota
diff --git a/openstackclient/tests/unit/volume/v2/fakes.py b/openstackclient/tests/unit/volume/v2/fakes.py
index d54faec7..d321c71a 100644
--- a/openstackclient/tests/unit/volume/v2/fakes.py
+++ b/openstackclient/tests/unit/volume/v2/fakes.py
@@ -954,3 +954,53 @@ class FakeType(object):
info=copy.deepcopy(encryption_info),
loaded=True)
return encryption_type
+
+
+class FakeQuota(object):
+ """Fake quota"""
+
+ @staticmethod
+ def create_one_vol_quota(attrs=None):
+ """Create one quota"""
+ attrs = attrs or {}
+
+ quota_attrs = {
+ 'id': 'project-id-' + uuid.uuid4().hex,
+ 'backups': 100,
+ 'backup_gigabytes': 100,
+ 'gigabytes': 10,
+ 'per_volume_gigabytes': 10,
+ 'snapshots': 0,
+ 'volumes': 10}
+
+ quota_attrs.update(attrs)
+
+ quota = fakes.FakeResource(
+ info=copy.deepcopy(quota_attrs),
+ loaded=True)
+ quota.project_id = quota_attrs['id']
+
+ return quota
+
+ @staticmethod
+ def create_one_default_vol_quota(attrs=None):
+ """Create one quota"""
+ attrs = attrs or {}
+
+ quota_attrs = {
+ 'id': 'project-id-' + uuid.uuid4().hex,
+ 'backups': 100,
+ 'backup_gigabytes': 100,
+ 'gigabytes': 100,
+ 'per_volume_gigabytes': 100,
+ 'snapshots': 100,
+ 'volumes': 100}
+
+ quota_attrs.update(attrs)
+
+ quota = fakes.FakeResource(
+ info=copy.deepcopy(quota_attrs),
+ loaded=True)
+ quota.project_id = quota_attrs['id']
+
+ return quota