summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2019-03-06 19:37:36 +0000
committerGerrit Code Review <review@openstack.org>2019-03-06 19:37:36 +0000
commit1d16eed45a75957e56908e62e1a0cb899853349b (patch)
tree514c1aa73cffb4b6ab6e163c153d6ff43c017657 /openstackclient
parentf5980f9508d8711283dfd866d331a6362499cf63 (diff)
parentc79de8a90bc1f1149b8302052580e5a76876724c (diff)
downloadpython-openstackclient-1d16eed45a75957e56908e62e1a0cb899853349b.tar.gz
Merge "Paginate over usage list to return all usages"
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/compute/v2/usage.py50
-rw-r--r--openstackclient/tests/unit/compute/v2/fakes.py1
-rw-r--r--openstackclient/tests/unit/compute/v2/test_usage.py26
3 files changed, 76 insertions, 1 deletions
diff --git a/openstackclient/compute/v2/usage.py b/openstackclient/compute/v2/usage.py
index 4320bf90..f84cd61d 100644
--- a/openstackclient/compute/v2/usage.py
+++ b/openstackclient/compute/v2/usage.py
@@ -15,8 +15,10 @@
"""Usage action implementations"""
+import collections
import datetime
+from novaclient import api_versions
from osc_lib.command import command
from osc_lib import utils
import six
@@ -24,6 +26,36 @@ import six
from openstackclient.i18n import _
+def _get_usage_marker(usage):
+ marker = None
+ if hasattr(usage, 'server_usages') and usage.server_usages:
+ marker = usage.server_usages[-1]['instance_id']
+ return marker
+
+
+def _get_usage_list_marker(usage_list):
+ marker = None
+ if usage_list:
+ marker = _get_usage_marker(usage_list[-1])
+ return marker
+
+
+def _merge_usage(usage, next_usage):
+ usage.server_usages.extend(next_usage.server_usages)
+ usage.total_hours += next_usage.total_hours
+ usage.total_memory_mb_usage += next_usage.total_memory_mb_usage
+ usage.total_vcpus_usage += next_usage.total_vcpus_usage
+ usage.total_local_gb_usage += next_usage.total_local_gb_usage
+
+
+def _merge_usage_list(usages, next_usage_list):
+ for next_usage in next_usage_list:
+ if next_usage.tenant_id in usages:
+ _merge_usage(usages[next_usage.tenant_id], next_usage)
+ else:
+ usages[next_usage.tenant_id] = next_usage
+
+
class ListUsage(command.Lister):
_description = _("List resource usage per project")
@@ -83,7 +115,23 @@ class ListUsage(command.Lister):
else:
end = now + datetime.timedelta(days=1)
- usage_list = compute_client.usage.list(start, end, detailed=True)
+ if compute_client.api_version < api_versions.APIVersion("2.40"):
+ usage_list = compute_client.usage.list(start, end, detailed=True)
+ else:
+ # If the number of instances used to calculate the usage is greater
+ # than CONF.api.max_limit, the usage will be split across multiple
+ # requests and the responses will need to be merged back together.
+ usages = collections.OrderedDict()
+ usage_list = compute_client.usage.list(start, end, detailed=True)
+ _merge_usage_list(usages, usage_list)
+ marker = _get_usage_list_marker(usage_list)
+ while marker:
+ next_usage_list = compute_client.usage.list(
+ start, end, detailed=True, marker=marker)
+ marker = _get_usage_list_marker(next_usage_list)
+ if marker:
+ _merge_usage_list(usages, next_usage_list)
+ usage_list = list(usages.values())
# Cache the project list
project_cache = {}
diff --git a/openstackclient/tests/unit/compute/v2/fakes.py b/openstackclient/tests/unit/compute/v2/fakes.py
index 234bbd9b..38f4ff67 100644
--- a/openstackclient/tests/unit/compute/v2/fakes.py
+++ b/openstackclient/tests/unit/compute/v2/fakes.py
@@ -1304,6 +1304,7 @@ class FakeUsage(object):
'local_gb': 1,
'memory_mb': 512,
'name': 'usage-name-' + uuid.uuid4().hex,
+ 'instance_id': uuid.uuid4().hex,
'state': 'active',
'uptime': 3600,
'vcpus': 1
diff --git a/openstackclient/tests/unit/compute/v2/test_usage.py b/openstackclient/tests/unit/compute/v2/test_usage.py
index a7aa1374..76dcc963 100644
--- a/openstackclient/tests/unit/compute/v2/test_usage.py
+++ b/openstackclient/tests/unit/compute/v2/test_usage.py
@@ -14,6 +14,7 @@
import datetime
import mock
+from novaclient import api_versions
from openstackclient.compute.v2 import usage
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
@@ -104,6 +105,31 @@ class TestUsageList(TestUsage):
self.assertEqual(self.columns, columns)
self.assertEqual(tuple(self.data), tuple(data))
+ def test_usage_list_with_pagination(self):
+ arglist = []
+ verifylist = [
+ ('start', None),
+ ('end', None),
+ ]
+
+ self.app.client_manager.compute.api_version = api_versions.APIVersion(
+ '2.40')
+ self.usage_mock.list.reset_mock()
+ self.usage_mock.list.side_effect = [self.usages, []]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.projects_mock.list.assert_called_with()
+ self.usage_mock.list.assert_has_calls([
+ mock.call(mock.ANY, mock.ANY, detailed=True),
+ mock.call(mock.ANY, mock.ANY, detailed=True,
+ marker=self.usages[0]['server_usages'][0]['instance_id'])
+ ])
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(tuple(self.data), tuple(data))
+
class TestUsageShow(TestUsage):