summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-02-05 16:53:53 +0000
committerGerrit Code Review <review@openstack.org>2018-02-05 16:53:53 +0000
commit5de74bef5c67f08811ab0c166df0230b01e4ed8a (patch)
treeb838d9cda69dabd72115b021978d0a7ba88e3399
parent68877e995973e0a78d8ea501b4c19e64b720e7e8 (diff)
parentd418b5f245f4cef4d35b8795aa6af8b98cd60141 (diff)
downloadpython-novaclient-5de74bef5c67f08811ab0c166df0230b01e4ed8a.tar.gz
Merge "Add CLI to show instance usage audit logs"
-rw-r--r--novaclient/tests/functional/v2/test_instance_usage_audit_log.py87
-rw-r--r--novaclient/tests/unit/v2/fakes.py82
-rw-r--r--novaclient/tests/unit/v2/test_instance_usage_audit_log.py37
-rw-r--r--novaclient/tests/unit/v2/test_shell.py11
-rw-r--r--novaclient/v2/client.py3
-rw-r--r--novaclient/v2/instance_usage_audit_log.py40
-rw-r--r--novaclient/v2/shell.py17
-rw-r--r--releasenotes/notes/show-instance-usage-audit-logs-7826b411fac1283b.yaml8
8 files changed, 285 insertions, 0 deletions
diff --git a/novaclient/tests/functional/v2/test_instance_usage_audit_log.py b/novaclient/tests/functional/v2/test_instance_usage_audit_log.py
new file mode 100644
index 00000000..5e7ce889
--- /dev/null
+++ b/novaclient/tests/functional/v2/test_instance_usage_audit_log.py
@@ -0,0 +1,87 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import datetime
+
+from oslo_utils import timeutils
+
+from novaclient.tests.functional import base
+
+
+class TestInstanceUsageAuditLogCLI(base.ClientTestBase):
+ COMPUTE_API_VERSION = '2.1'
+
+ # NOTE(takashin): By default, 'instance_usage_audit' is False in nova.
+ # So the instance usage audit log is not recoreded.
+ # Therefore an empty result can be got.
+ # But it is tested here to call APIs and get responses normally.
+
+ @staticmethod
+ def _get_begin_end_time():
+ current = timeutils.utcnow()
+
+ end = datetime.datetime(day=1, month=current.month, year=current.year)
+ year = end.year
+
+ if current.month == 1:
+ year -= 1
+ month = 12
+ else:
+ month = current.month - 1
+
+ begin = datetime.datetime(day=1, month=month, year=year)
+
+ return (begin, end)
+
+ def test_get_os_instance_usage_audit_log(self):
+ (begin, end) = self._get_begin_end_time()
+ expected = {
+ 'hosts_not_run': '[]',
+ 'log': '{}',
+ 'num_hosts': '0',
+ 'num_hosts_done': '0',
+ 'num_hosts_not_run': '0',
+ 'num_hosts_running': '0',
+ 'overall_status': 'ALL hosts done. 0 errors.',
+ 'total_errors': '0',
+ 'total_instances': '0',
+ 'period_beginning': str(begin),
+ 'period_ending': str(end)
+ }
+
+ output = self.nova('instance-usage-audit-log')
+
+ for key in expected.keys():
+ self.assertEqual(expected[key],
+ self._get_value_from_the_table(output, key))
+
+ def test_get_os_instance_usage_audit_log_with_before(self):
+ expected = {
+ 'hosts_not_run': '[]',
+ 'log': '{}',
+ 'num_hosts': '0',
+ 'num_hosts_done': '0',
+ 'num_hosts_not_run': '0',
+ 'num_hosts_running': '0',
+ 'overall_status': 'ALL hosts done. 0 errors.',
+ 'total_errors': '0',
+ 'total_instances': '0',
+ 'period_beginning': '2016-11-01 00:00:00',
+ 'period_ending': '2016-12-01 00:00:00'
+ }
+
+ output = self.nova(
+ 'instance-usage-audit-log --before "2016-12-10 13:59:59.999999"')
+
+ for key in expected.keys():
+ self.assertEqual(expected[key],
+ self._get_value_from_the_table(output, key))
diff --git a/novaclient/tests/unit/v2/fakes.py b/novaclient/tests/unit/v2/fakes.py
index bd69bf9d..803dc41e 100644
--- a/novaclient/tests/unit/v2/fakes.py
+++ b/novaclient/tests/unit/v2/fakes.py
@@ -124,6 +124,8 @@ class FakeSessionClient(base_client.SessionClient):
munged_url = munged_url.replace(' ', '_')
munged_url = munged_url.replace('!', '_')
munged_url = munged_url.replace('@', '_')
+ munged_url = munged_url.replace('%20', '_')
+ munged_url = munged_url.replace('%3A', '_')
callback = "%s_%s" % (method.lower(), munged_url)
if url is None or callback == "get_http:__nova_api:8774":
@@ -2006,6 +2008,86 @@ class FakeSessionClient(base_client.SessionClient):
return (200, FAKE_RESPONSE_HEADERS, {
"instanceAction": action})
+ def get_os_instance_usage_audit_log(self, **kw):
+ return (200, FAKE_RESPONSE_HEADERS, {
+ "instance_usage_audit_logs": {
+ "hosts_not_run": ["samplehost3"],
+ "log": {
+ "samplehost0": {
+ "errors": 1,
+ "instances": 1,
+ "message": ("Instance usage audit ran for host "
+ "samplehost0, 1 instances in 0.01 "
+ "seconds."),
+ "state": "DONE"
+ },
+ "samplehost1": {
+ "errors": 1,
+ "instances": 2,
+ "message": ("Instance usage audit ran for host "
+ "samplehost1, 2 instances in 0.01 "
+ "seconds."),
+ "state": "DONE"
+ },
+ "samplehost2": {
+ "errors": 1,
+ "instances": 3,
+ "message": ("Instance usage audit ran for host "
+ "samplehost2, 3 instances in 0.01 "
+ "seconds."),
+ "state": "DONE"
+ },
+ },
+ "num_hosts": 4,
+ "num_hosts_done": 3,
+ "num_hosts_not_run": 1,
+ "num_hosts_running": 0,
+ "overall_status": "3 of 4 hosts done. 3 errors.",
+ "period_beginning": "2012-06-01 00:00:00",
+ "period_ending": "2012-07-01 00:00:00",
+ "total_errors": 3,
+ "total_instances": 6}})
+
+ def get_os_instance_usage_audit_log_2016_12_10_13_59_59_999999(self, **kw):
+ return (200, FAKE_RESPONSE_HEADERS, {
+ "instance_usage_audit_log": {
+ "hosts_not_run": ["samplehost3"],
+ "log": {
+ "samplehost0": {
+ "errors": 1,
+ "instances": 1,
+ "message": ("Instance usage audit ran for host "
+ "samplehost0, 1 instances in 0.01 "
+ "seconds."),
+ "state": "DONE"
+ },
+ "samplehost1": {
+ "errors": 1,
+ "instances": 2,
+ "message": ("Instance usage audit ran for host "
+ "samplehost1, 2 instances in 0.01 "
+ "seconds."),
+ "state": "DONE"
+ },
+ "samplehost2": {
+ "errors": 1,
+ "instances": 3,
+ "message": ("Instance usage audit ran for host "
+ "samplehost2, 3 instances in 0.01 "
+ "seconds."),
+ "state": "DONE"
+ },
+ },
+ "num_hosts": 4,
+ "num_hosts_done": 3,
+ "num_hosts_not_run": 1,
+ "num_hosts_running": 0,
+ "overall_status": "3 of 4 hosts done. 3 errors.",
+ "period_beginning": "2012-06-01 00:00:00",
+ "period_ending": "2012-07-01 00:00:00",
+ "total_errors": 3,
+ "total_instances": 6}})
+
def post_servers_uuid1_action(self, **kw):
return 202, {}, {}
diff --git a/novaclient/tests/unit/v2/test_instance_usage_audit_log.py b/novaclient/tests/unit/v2/test_instance_usage_audit_log.py
new file mode 100644
index 00000000..148ebbda
--- /dev/null
+++ b/novaclient/tests/unit/v2/test_instance_usage_audit_log.py
@@ -0,0 +1,37 @@
+# Copyright 2013 Rackspace Hosting
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from novaclient import api_versions
+from novaclient.tests.unit import utils
+from novaclient.tests.unit.v2 import fakes
+
+
+class InstanceUsageAuditLogTests(utils.TestCase):
+ def setUp(self):
+ super(InstanceUsageAuditLogTests, self).setUp()
+ self.cs = fakes.FakeClient(api_versions.APIVersion("2.1"))
+
+ def test_instance_usage_audit_log(self):
+ audit_log = self.cs.instance_usage_audit_log.get()
+ self.assert_request_id(audit_log, fakes.FAKE_REQUEST_ID_LIST)
+ self.cs.assert_called('GET', '/os-instance_usage_audit_log')
+
+ def test_instance_usage_audit_log_with_before(self):
+ audit_log = self.cs.instance_usage_audit_log.get(
+ before='2016-12-10 13:59:59.999999')
+ self.assert_request_id(audit_log, fakes.FAKE_REQUEST_ID_LIST)
+ self.cs.assert_called(
+ 'GET',
+ '/os-instance_usage_audit_log/2016-12-10%2013%3A59%3A59.999999')
diff --git a/novaclient/tests/unit/v2/test_shell.py b/novaclient/tests/unit/v2/test_shell.py
index 2dc0f395..785b9683 100644
--- a/novaclient/tests/unit/v2/test_shell.py
+++ b/novaclient/tests/unit/v2/test_shell.py
@@ -3210,6 +3210,17 @@ class ShellTest(utils.TestCase):
api_version='2.58')
self.assertIn('Invalid changes-since value', six.text_type(ex))
+ def test_instance_usage_audit_log(self):
+ self.run_command('instance-usage-audit-log')
+ self.assert_called('GET', '/os-instance_usage_audit_log')
+
+ def test_instance_usage_audit_log_with_before(self):
+ self.run_command(
+ ["instance-usage-audit-log", "--before",
+ "2016-12-10 13:59:59.999999"])
+ self.assert_called('GET', '/os-instance_usage_audit_log'
+ '/2016-12-10%2013%3A59%3A59.999999')
+
def test_cell_show(self):
self.run_command('cell-show child_cell')
self.assert_called('GET', '/os-cells/child_cell')
diff --git a/novaclient/v2/client.py b/novaclient/v2/client.py
index 1f543a82..bc66575f 100644
--- a/novaclient/v2/client.py
+++ b/novaclient/v2/client.py
@@ -29,6 +29,7 @@ from novaclient.v2 import flavors
from novaclient.v2 import hypervisors
from novaclient.v2 import images
from novaclient.v2 import instance_action
+from novaclient.v2 import instance_usage_audit_log
from novaclient.v2 import keypairs
from novaclient.v2 import limits
from novaclient.v2 import list_extensions
@@ -169,6 +170,8 @@ class Client(object):
assisted_volume_snapshots.AssistedSnapshotManager(self)
self.cells = cells.CellsManager(self)
self.instance_action = instance_action.InstanceActionManager(self)
+ self.instance_usage_audit_log = \
+ instance_usage_audit_log.InstanceUsageAuditLogManager(self)
self.list_extensions = list_extensions.ListExtManager(self)
self.migrations = migrations.MigrationManager(self)
self.server_external_events = \
diff --git a/novaclient/v2/instance_usage_audit_log.py b/novaclient/v2/instance_usage_audit_log.py
new file mode 100644
index 00000000..19b588e9
--- /dev/null
+++ b/novaclient/v2/instance_usage_audit_log.py
@@ -0,0 +1,40 @@
+# Copyright 2013 Rackspace Hosting
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from six.moves.urllib import parse
+
+from novaclient import base
+
+
+class InstanceUsageAuditLog(base.Resource):
+ pass
+
+
+class InstanceUsageAuditLogManager(base.Manager):
+ resource_class = InstanceUsageAuditLog
+
+ def get(self, before=None):
+ """Get server usage audits.
+
+ :param before: Filters the response by the date and time
+ before which to list usage audits.
+ """
+ if before:
+ return self._get('/os-instance_usage_audit_log/%s' %
+ parse.quote(before, safe=''),
+ 'instance_usage_audit_log')
+ else:
+ return self._get('/os-instance_usage_audit_log',
+ 'instance_usage_audit_logs')
diff --git a/novaclient/v2/shell.py b/novaclient/v2/shell.py
index 1f062946..e73bd504 100644
--- a/novaclient/v2/shell.py
+++ b/novaclient/v2/shell.py
@@ -5120,3 +5120,20 @@ def do_migration_list(cs, args):
changes_since=args.changes_since)
# TODO(yikun): Output a "Marker" column if there is a next link?
_print_migrations(cs, migrations)
+
+
+@utils.arg(
+ '--before',
+ dest='before',
+ metavar='<before>',
+ default=None,
+ help=_("Filters the response by the date and time before which to list "
+ "usage audits. The date and time stamp format is as follows: "
+ "CCYY-MM-DD hh:mm:ss.NNNNNN ex 2015-08-27 09:49:58 or "
+ "2015-08-27 09:49:58.123456."))
+def do_instance_usage_audit_log(cs, args):
+ """List/Get server usage audits."""
+ audit_log = cs.instance_usage_audit_log.get(before=args.before).to_dict()
+ if 'hosts_not_run' in audit_log:
+ audit_log['hosts_not_run'] = pprint.pformat(audit_log['hosts_not_run'])
+ utils.print_dict(audit_log)
diff --git a/releasenotes/notes/show-instance-usage-audit-logs-7826b411fac1283b.yaml b/releasenotes/notes/show-instance-usage-audit-logs-7826b411fac1283b.yaml
new file mode 100644
index 00000000..57abbd30
--- /dev/null
+++ b/releasenotes/notes/show-instance-usage-audit-logs-7826b411fac1283b.yaml
@@ -0,0 +1,8 @@
+---
+features:
+ - Added new client API and CLI (``nova instance-usage-audit-log``)
+ to get server usage audit logs.
+ By default, it lists usage audits for all servers on all
+ compute hosts where usage auditing is configured.
+ If you specify the ``--before`` option, the result is filtered
+ by the date and time before which to list server usage audits.