From 0f7404d7a8f5b6948ae050f6bd434483be42522d Mon Sep 17 00:00:00 2001 From: Andrew Laski Date: Mon, 25 Mar 2013 12:56:34 -0400 Subject: [PATCH] Add support for retrieving instance-actions info Adds an extension for querying instance-actions info on an instance. There are two new commands: 'instance-action-list ' which lists actions that have been recorded for that instance, and 'instance-action ' which provides more details for the action with that request_id on that server. Change-Id: I22492d682d50b78f522f10269221fea9483df6dd --- novaclient/v1_1/contrib/instance_action.py | 65 +++++++++++++++++++++ tests/v1_1/contrib/test_instance_actions.py | 41 +++++++++++++ tests/v1_1/fakes.py | 20 +++++++ tests/v1_1/test_shell.py | 9 +++ 4 files changed, 135 insertions(+) create mode 100644 novaclient/v1_1/contrib/instance_action.py create mode 100644 tests/v1_1/contrib/test_instance_actions.py diff --git a/novaclient/v1_1/contrib/instance_action.py b/novaclient/v1_1/contrib/instance_action.py new file mode 100644 index 000000000..5e9c64db7 --- /dev/null +++ b/novaclient/v1_1/contrib/instance_action.py @@ -0,0 +1,65 @@ +# 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. + +import pprint + +from novaclient import base +from novaclient import utils + + +class InstanceActionManager(base.ManagerWithFind): + resource_class = base.Resource + + def get(self, server, request_id): + """ + Get details of an action performed on an instance. + + :param request_id: The request_id of the action to get. + """ + return self._get("/servers/%s/os-instance-actions/%s" % + (base.getid(server), request_id), 'instanceAction') + + def list(self, server): + """ + Get a list of actions performed on an server. + """ + return self._list('/servers/%s/os-instance-actions' % + base.getid(server), 'instanceActions') + + +@utils.arg('server', + metavar='', + help='Name or UUID of the server to show an action for.') +@utils.arg('request_id', + metavar='', + help='Request ID of the action to get.') +def do_instance_action(cs, args): + """Show an action.""" + server = utils.find_resource(cs.servers, args.server) + action_resource = cs.instance_action.get(server, args.request_id) + action = action_resource._info + if 'events' in action: + action['events'] = pprint.pformat(action['events']) + utils.print_dict(action) + + +@utils.arg('server', + metavar='', + help='Name or UUID of the server to list actions for.') +def do_instance_action_list(cs, args): + """List actions on a server.""" + server = utils.find_resource(cs.servers, args.server) + actions = cs.instance_action.list(server) + utils.print_list(actions, ['Action', 'Request_ID', 'Message']) diff --git a/tests/v1_1/contrib/test_instance_actions.py b/tests/v1_1/contrib/test_instance_actions.py new file mode 100644 index 000000000..8f8e1cd58 --- /dev/null +++ b/tests/v1_1/contrib/test_instance_actions.py @@ -0,0 +1,41 @@ +# 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 extension +from novaclient.v1_1.contrib import instance_action + +from tests import utils +from tests.v1_1.contrib import fakes + + +extensions = [ + extension.Extension(instance_action.__name__.split(".")[-1], + instance_action), +] +cs = fakes.FakeClient(extensions=extensions) + + +class InstanceActionExtensionTests(utils.TestCase): + def test_list_instance_actions(self): + server_uuid = '1234' + cs.instance_action.list(server_uuid) + cs.assert_called('GET', '/servers/%s/os-instance-actions' % + server_uuid) + + def test_get_instance_action(self): + server_uuid = '1234' + request_id = 'req-abcde12345' + cs.instance_action.get(server_uuid, request_id) + cs.assert_called('GET', '/servers/%s/os-instance-actions/%s' % + (server_uuid, request_id)) diff --git a/tests/v1_1/fakes.py b/tests/v1_1/fakes.py index 7f082d5fd..27e1cfbfe 100644 --- a/tests/v1_1/fakes.py +++ b/tests/v1_1/fakes.py @@ -1693,3 +1693,23 @@ class FakeHTTPClient(base_client.HTTPClient): def delete_servers_1234_os_volume_attachments_Work(self, **kw): return (200, {}, {}) + + def get_servers_1234_os_instance_actions(self, **kw): + return (200, {}, {"instanceActions": + [{"instance_uuid": "1234", + "user_id": "b968c25e04ab405f9fe4e6ca54cce9a5", + "start_time": "2013-03-25T13:45:09.000000", + "request_id": "req-abcde12345", + "action": "create", + "message": None, + "project_id": "04019601fe3648c0abd4f4abfb9e6106"}]}) + + def get_servers_1234_os_instance_actions_req_abcde12345(self, **kw): + return (200, {}, {"instanceAction": + {"instance_uuid": "1234", + "user_id": "b968c25e04ab405f9fe4e6ca54cce9a5", + "start_time": "2013-03-25T13:45:09.000000", + "request_id": "req-abcde12345", + "action": "create", + "message": None, + "project_id": "04019601fe3648c0abd4f4abfb9e6106"}}) diff --git a/tests/v1_1/test_shell.py b/tests/v1_1/test_shell.py index 13b018a0e..337a653b5 100644 --- a/tests/v1_1/test_shell.py +++ b/tests/v1_1/test_shell.py @@ -1275,3 +1275,12 @@ class ShellTest(utils.TestCase): self.run_command('volume-detach sample-server Work') self.assert_called('DELETE', '/servers/1234/os-volume_attachments/Work') + + def test_instance_action_list(self): + self.run_command('instance-action-list sample-server') + self.assert_called('GET', '/servers/1234/os-instance-actions') + + def test_instance_action_get(self): + self.run_command('instance-action sample-server req-abcde12345') + self.assert_called('GET', + '/servers/1234/os-instance-actions/req-abcde12345')