summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/compute/v2/server_event.py117
-rw-r--r--openstackclient/tests/functional/compute/v2/test_server_event.py97
-rw-r--r--openstackclient/tests/unit/compute/v2/fakes.py44
-rw-r--r--openstackclient/tests/unit/compute/v2/test_server_event.py167
4 files changed, 425 insertions, 0 deletions
diff --git a/openstackclient/compute/v2/server_event.py b/openstackclient/compute/v2/server_event.py
new file mode 100644
index 00000000..ccb19ef7
--- /dev/null
+++ b/openstackclient/compute/v2/server_event.py
@@ -0,0 +1,117 @@
+# Copyright 2017 Huawei, Inc. 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.
+#
+
+"""Compute v2 Server operation event implementations"""
+
+import logging
+import six
+
+from osc_lib.command import command
+from osc_lib import utils
+
+from openstackclient.i18n import _
+
+
+LOG = logging.getLogger(__name__)
+
+
+class ListServerEvent(command.Lister):
+ _description = _("List recent events of a server")
+
+ def get_parser(self, prog_name):
+ parser = super(ListServerEvent, self).get_parser(prog_name)
+ parser.add_argument(
+ 'server',
+ metavar='<server>',
+ help=_('Server to list events (name or ID)'),
+ )
+ parser.add_argument(
+ '--long',
+ action='store_true',
+ default=False,
+ help=_("List additional fields in output")
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ compute_client = self.app.client_manager.compute
+ server_id = utils.find_resource(compute_client.servers,
+ parsed_args.server).id
+ data = compute_client.instance_action.list(server_id)
+
+ if parsed_args.long:
+ columns = (
+ 'request_id',
+ 'instance_uuid',
+ 'action',
+ 'start_time',
+ 'message',
+ 'project_id',
+ 'user_id',
+ )
+ column_headers = (
+ 'Request ID',
+ 'Server ID',
+ 'Action',
+ 'Start Time',
+ 'Message',
+ 'Project ID',
+ 'User ID',
+ )
+ else:
+ columns = (
+ 'request_id',
+ 'instance_uuid',
+ 'action',
+ 'start_time',
+ )
+ column_headers = (
+ 'Request ID',
+ 'Server ID',
+ 'Action',
+ 'Start Time',
+ )
+
+ return (column_headers,
+ (utils.get_item_properties(
+ s, columns,
+ ) for s in data))
+
+
+class ShowServerEvent(command.ShowOne):
+ _description = _("Show server event details")
+
+ def get_parser(self, prog_name):
+ parser = super(ShowServerEvent, self).get_parser(prog_name)
+ parser.add_argument(
+ 'server',
+ metavar='<server>',
+ help=_('Server to show event details (name or ID)'),
+ )
+ parser.add_argument(
+ 'request_id',
+ metavar='<request-id>',
+ help=_('Request ID of the event to show (ID only)'),
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ compute_client = self.app.client_manager.compute
+ server_id = utils.find_resource(compute_client.servers,
+ parsed_args.server).id
+ action_detail = compute_client.instance_action.get(
+ server_id, parsed_args.request_id)
+
+ return zip(*sorted(six.iteritems(action_detail._info)))
diff --git a/openstackclient/tests/functional/compute/v2/test_server_event.py b/openstackclient/tests/functional/compute/v2/test_server_event.py
new file mode 100644
index 00000000..6be5822f
--- /dev/null
+++ b/openstackclient/tests/functional/compute/v2/test_server_event.py
@@ -0,0 +1,97 @@
+# Copyright 2017 Huawei, Inc. 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.
+#
+
+import json
+import uuid
+
+from openstackclient.tests.functional import base
+from openstackclient.tests.functional.compute.v2 import test_server
+
+
+class ServerEventTests(base.TestCase):
+ """Functional tests for server event."""
+
+ def setUp(self):
+ super(ServerEventTests, self).setUp()
+ _flavor = test_server.ServerTests.get_flavor()
+ _image = test_server.ServerTests.get_image()
+ _network = test_server.ServerTests.get_network()
+ self.server_name = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ 'server create -f json ' +
+ '--flavor ' + _flavor + ' ' +
+ '--image ' + _image + ' ' +
+ _network + ' ' +
+ '--wait ' +
+ self.server_name
+ ))
+ if not cmd_output:
+ self.fail('Server has not been created!')
+ self.addCleanup(self.openstack, 'server delete ' + self.server_name)
+ self.assertEqual(self.server_name, cmd_output['name'])
+ self.server_id = cmd_output.get('id')
+
+ def test_server_event_list_and_show(self):
+ """Test list, show server event"""
+ # Test 'server event list' for creating
+ cmd_output = json.loads(self.openstack(
+ 'server event list -f json ' + self.server_name
+ ))
+ request_id = None
+ for each_event in cmd_output:
+ self.assertNotIn('Message', each_event)
+ self.assertNotIn('Project ID', each_event)
+ self.assertNotIn('User ID', each_event)
+ if each_event.get('Action') == 'create':
+ self.assertEqual(self.server_id, each_event.get('Server ID'))
+ request_id = each_event.get('Request ID')
+ break
+ self.assertIsNotNone(request_id)
+ # Test 'server event show' for creating
+ cmd_output = json.loads(self.openstack(
+ 'server event show -f json ' + self.server_name + ' ' + request_id
+ ))
+ self.assertEqual(self.server_id, cmd_output.get('instance_uuid'))
+ self.assertEqual(request_id, cmd_output.get('request_id'))
+ self.assertEqual('create', cmd_output.get('action'))
+ self.assertIsNotNone(cmd_output.get('events'))
+ self.assertIsInstance(cmd_output.get('events'), list)
+
+ # Reboot server, trigger reboot event
+ self.openstack('server reboot --wait ' + self.server_name)
+ # Test 'server event list --long' for rebooting
+ cmd_output = json.loads(self.openstack(
+ 'server event list --long -f json ' + self.server_name
+ ))
+ request_id = None
+ for each_event in cmd_output:
+ self.assertIn('Message', each_event)
+ self.assertIn('Project ID', each_event)
+ self.assertIn('User ID', each_event)
+ if each_event.get('Action') == 'reboot':
+ request_id = each_event.get('Request ID')
+ self.assertEqual(self.server_id, each_event.get('Server ID'))
+ break
+ self.assertIsNotNone(request_id)
+ # Test 'server event show' for rebooting
+ cmd_output = json.loads(self.openstack(
+ 'server event show -f json ' + self.server_name + ' ' + request_id
+ ))
+
+ self.assertEqual(self.server_id, cmd_output.get('instance_uuid'))
+ self.assertEqual(request_id, cmd_output.get('request_id'))
+ self.assertEqual('reboot', cmd_output.get('action'))
+ self.assertIsNotNone(cmd_output.get('events'))
+ self.assertIsInstance(cmd_output.get('events'), list)
diff --git a/openstackclient/tests/unit/compute/v2/fakes.py b/openstackclient/tests/unit/compute/v2/fakes.py
index 4fe735b6..bbb770bb 100644
--- a/openstackclient/tests/unit/compute/v2/fakes.py
+++ b/openstackclient/tests/unit/compute/v2/fakes.py
@@ -204,6 +204,9 @@ class FakeComputev2Client(object):
self.server_groups = mock.Mock()
self.server_groups.resource_class = fakes.FakeResource(None, {})
+ self.instance_action = mock.Mock()
+ self.instance_action.resource_class = fakes.FakeResource(None, {})
+
self.auth_token = kwargs['token']
self.management_url = kwargs['endpoint']
@@ -656,6 +659,47 @@ class FakeServer(object):
return mock.Mock(side_effect=servers)
+class FakeServerEvent(object):
+ """Fake one or more server event."""
+
+ @staticmethod
+ def create_one_server_event(attrs=None):
+ """Create a fake server event.
+
+ :param attrs:
+ A dictionary with all attributes
+ :return:
+ A FakeResource object, with id and other attributes
+ """
+ attrs = attrs or {}
+
+ # Set default attributes
+ server_event_info = {
+ "instance_uuid": "server-event-" + uuid.uuid4().hex,
+ "user_id": "user-id-" + uuid.uuid4().hex,
+ "start_time": "2017-02-27T07:47:13.000000",
+ "request_id": "req-" + uuid.uuid4().hex,
+ "action": "create",
+ "message": None,
+ "project_id": "project-id-" + uuid.uuid4().hex,
+ "events": [{
+ "finish_time": "2017-02-27T07:47:25.000000",
+ "start_time": "2017-02-27T07:47:15.000000",
+ "traceback": None,
+ "event": "compute__do_build_and_run_instance",
+ "result": "Success"
+ }]
+ }
+ # Overwrite default attributes
+ server_event_info.update(attrs)
+
+ server_event = fakes.FakeResource(
+ info=copy.deepcopy(server_event_info),
+ loaded=True,
+ )
+ return server_event
+
+
class FakeService(object):
"""Fake one or more services."""
diff --git a/openstackclient/tests/unit/compute/v2/test_server_event.py b/openstackclient/tests/unit/compute/v2/test_server_event.py
new file mode 100644
index 00000000..5c94891a
--- /dev/null
+++ b/openstackclient/tests/unit/compute/v2/test_server_event.py
@@ -0,0 +1,167 @@
+# Copyright 2017 Huawei, Inc. 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 openstackclient.compute.v2 import server_event
+from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
+
+
+class TestServerEvent(compute_fakes.TestComputev2):
+
+ fake_server = compute_fakes.FakeServer.create_one_server()
+
+ def setUp(self):
+ super(TestServerEvent, self).setUp()
+
+ self.servers_mock = self.app.client_manager.compute.servers
+ self.servers_mock.reset_mock()
+ self.events_mock = self.app.client_manager.compute.instance_action
+ self.events_mock.reset_mock()
+
+ self.servers_mock.get.return_value = self.fake_server
+
+
+class TestListServerEvent(TestServerEvent):
+
+ fake_event = compute_fakes.FakeServerEvent.create_one_server_event()
+
+ columns = (
+ 'Request ID',
+ 'Server ID',
+ 'Action',
+ 'Start Time',
+ )
+ data = ((
+ fake_event.request_id,
+ fake_event.instance_uuid,
+ fake_event.action,
+ fake_event.start_time,
+ ), )
+
+ long_columns = (
+ 'Request ID',
+ 'Server ID',
+ 'Action',
+ 'Start Time',
+ 'Message',
+ 'Project ID',
+ 'User ID',
+ )
+ long_data = ((
+ fake_event.request_id,
+ fake_event.instance_uuid,
+ fake_event.action,
+ fake_event.start_time,
+ fake_event.message,
+ fake_event.project_id,
+ fake_event.user_id,
+ ), )
+
+ def setUp(self):
+ super(TestListServerEvent, self).setUp()
+
+ self.events_mock.list.return_value = [self.fake_event, ]
+ self.cmd = server_event.ListServerEvent(self.app, None)
+
+ def test_server_event_list(self):
+ arglist = [
+ self.fake_server.name,
+ ]
+ verifylist = [
+ ('server', self.fake_server.name),
+ ('long', False),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.servers_mock.get.assert_called_once_with(self.fake_server.name)
+ self.events_mock.list.assert_called_once_with(self.fake_server.id)
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, tuple(data))
+
+ def test_server_event_list_long(self):
+ arglist = [
+ '--long',
+ self.fake_server.name,
+ ]
+ verifylist = [
+ ('server', self.fake_server.name),
+ ('long', True),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.servers_mock.get.assert_called_once_with(self.fake_server.name)
+ self.events_mock.list.assert_called_once_with(self.fake_server.id)
+
+ self.assertEqual(self.long_columns, columns)
+ self.assertEqual(self.long_data, tuple(data))
+
+
+class TestShowServerEvent(TestServerEvent):
+
+ fake_event = compute_fakes.FakeServerEvent.create_one_server_event()
+
+ columns = (
+ 'action',
+ 'events',
+ 'instance_uuid',
+ 'message',
+ 'project_id',
+ 'request_id',
+ 'start_time',
+ 'user_id',
+ )
+ data = (
+ fake_event.action,
+ fake_event.events,
+ fake_event.instance_uuid,
+ fake_event.message,
+ fake_event.project_id,
+ fake_event.request_id,
+ fake_event.start_time,
+ fake_event.user_id,
+ )
+
+ def setUp(self):
+ super(TestShowServerEvent, self).setUp()
+
+ self.events_mock.get.return_value = self.fake_event
+ self.cmd = server_event.ShowServerEvent(self.app, None)
+
+ def test_server_event_show(self):
+ arglist = [
+ self.fake_server.name,
+ self.fake_event.request_id,
+ ]
+ verifylist = [
+ ('server', self.fake_server.name),
+ ('request_id', self.fake_event.request_id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.servers_mock.get.assert_called_once_with(self.fake_server.name)
+ self.events_mock.get.assert_called_once_with(
+ self.fake_server.id, self.fake_event.request_id)
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)