Merge "Fix networking quota usage show"

This commit is contained in:
Zuul 2025-03-25 13:13:29 +00:00 committed by Gerrit Code Review
commit 866009211f
3 changed files with 67 additions and 17 deletions
openstackclient
common
tests
functional/common
unit/common

@ -176,25 +176,37 @@ def get_network_quotas(
default=False,
):
def _network_quota_to_dict(network_quota, detail=False):
if not isinstance(network_quota, dict):
dict_quota = network_quota.to_dict()
else:
dict_quota = network_quota
dict_quota = network_quota.to_dict(computed=False)
result = {}
if not detail:
return dict_quota
# Neutron returns quota details in dict which is in format like:
# {'resource_name': {'in_use': X, 'limit': Y, 'reserved': Z},
# 'resource_name_2': {'in_use': X2, 'limit': Y2, 'reserved': Z2}}
#
# but Nova and Cinder returns quota in different format, like:
# {'resource_name': X,
# 'resource_name_2': X2,
# 'usage': {
# 'resource_name': Y,
# 'resource_name_2': Y2
# },
# 'reserved': {
# 'resource_name': Z,
# 'resource_name_2': Z2
# }}
#
# so we need to make conversion to have data in same format from
# all of the services
result = {"usage": {}, "reservation": {}}
for key, values in dict_quota.items():
if values is None:
continue
# NOTE(slaweq): Neutron returns values with key "used" but Nova for
# example returns same data with key "in_use" instead. Because of
# that we need to convert Neutron key to the same as is returned
# from Nova to make result more consistent
if isinstance(values, dict) and 'used' in values:
values['in_use'] = values.pop("used")
result[key] = values
if isinstance(values, dict):
result[key] = values['limit']
result["reservation"][key] = values['reserved']
result["usage"][key] = values['used']
return result
@ -756,6 +768,19 @@ and ``server-group-members`` output for a given quota class."""
)
info = {}
if parsed_args.usage:
info["reservation"] = compute_quota_info.pop("reservation", {})
info["reservation"].update(
volume_quota_info.pop("reservation", {})
)
info["reservation"].update(
network_quota_info.pop("reservation", {})
)
info["usage"] = compute_quota_info.pop("usage", {})
info["usage"].update(volume_quota_info.pop("usage", {}))
info["usage"].update(network_quota_info.pop("usage", {}))
info.update(compute_quota_info)
info.update(volume_quota_info)
info.update(network_quota_info)

@ -250,6 +250,8 @@ class QuotaTests(base.TestCase):
row_headers = [str(r) for r in row.keys()]
self.assertEqual(sorted(expected_headers), sorted(row_headers))
resources.append(row['Resource'])
for header in expected_headers[1:]:
self.assertIsInstance(row[header], int)
# Ensure that returned quota has network quota...
self.assertIn("networks", resources)
# ...and compute quota

@ -955,6 +955,23 @@ class TestQuotaSet(TestQuota):
class TestQuotaShow(TestQuota):
_network_quota_details = {
'floating_ips': {'limit': 0, 'reserved': 0, 'used': 0},
'health_monitors': {'limit': 0, 'reserved': 0, 'used': 0},
'l7_policies': {'limit': 0, 'reserved': 0, 'used': 0},
'listeners': {'limit': 0, 'reserved': 0, 'used': 0},
'load_balancers': {'limit': 0, 'reserved': 0, 'used': 0},
'networks': {'limit': 0, 'reserved': 0, 'used': 0},
'pools': {'limit': 0, 'reserved': 0, 'used': 0},
'ports': {'limit': 0, 'reserved': 0, 'used': 0},
'rbac_policies': {'limit': 0, 'reserved': 0, 'used': 0},
'routers': {'limit': 0, 'reserved': 0, 'used': 0},
'security_group_rules': {'limit': 0, 'reserved': 0, 'used': 0},
'security_groups': {'limit': 0, 'reserved': 0, 'used': 0},
'subnet_pools': {'limit': 0, 'reserved': 0, 'used': 0},
'subnets': {'limit': 0, 'reserved': 0, 'used': 0},
}
def setUp(self):
super().setUp()
@ -980,9 +997,15 @@ class TestQuotaShow(TestQuota):
self.default_volume_quotas
)
self.network_client.get_quota.return_value = (
sdk_fakes.generate_fake_resource(_network_quota_set.Quota)
)
def get_network_quota_mock(*args, **kwargs):
if kwargs.get("details"):
return sdk_fakes.generate_fake_resource(
_network_quota_set.QuotaDetails,
**self._network_quota_details,
)
return sdk_fakes.generate_fake_resource(_network_quota_set.Quota)
self.network_client.get_quota.side_effect = get_network_quota_mock
self.default_network_quotas = sdk_fakes.generate_fake_resource(
_network_quota_set.QuotaDefault
)