diff --git a/senlinclient/osc/v1/action.py b/senlinclient/osc/v1/action.py index 3e07cd2..c064dac 100644 --- a/senlinclient/osc/v1/action.py +++ b/senlinclient/osc/v1/action.py @@ -13,8 +13,12 @@ """Clustering v1 action implementations""" import logging +import six from cliff import lister +from cliff import show +from openstack import exceptions as sdk_exc +from openstackclient.common import exceptions as exc from openstackclient.common import utils from senlinclient.common.i18n import _ @@ -103,3 +107,40 @@ class ListAction(lister.Lister): (utils.get_item_properties(a, columns, formatters=formatters) for a in actions) ) + + +class ShowAction(show.ShowOne): + """Show detailed info about the specified action.""" + + log = logging.getLogger(__name__ + ".ShowAction") + + def get_parser(self, prog_name): + parser = super(ShowAction, self).get_parser(prog_name) + parser.add_argument( + 'action', + metavar='', + help=_('Name or ID of the action to show the details for') + ) + return parser + + def take_action(self, parsed_args): + self.log.debug("take_action(%s)", parsed_args) + + senlin_client = self.app.client_manager.clustering + try: + action = senlin_client.get_action(parsed_args.action) + except sdk_exc.ResourceNotFound: + raise exc.CommandError(_('Action not found: %s') + % parsed_args.action) + + formatters = { + 'inputs': senlin_utils.json_formatter, + 'outputs': senlin_utils.json_formatter, + 'metadata': senlin_utils.json_formatter, + 'data': senlin_utils.json_formatter, + 'depends_on': senlin_utils.list_formatter, + 'depended_by': senlin_utils.list_formatter, + } + columns = list(six.iterkeys(action)) + return columns, utils.get_dict_properties(action.to_dict(), columns, + formatters=formatters) diff --git a/senlinclient/tests/unit/osc/v1/test_action.py b/senlinclient/tests/unit/osc/v1/test_action.py index 5b43432..a6cb553 100644 --- a/senlinclient/tests/unit/osc/v1/test_action.py +++ b/senlinclient/tests/unit/osc/v1/test_action.py @@ -15,6 +15,7 @@ import mock from openstack.cluster.v1 import action as sdk_action from openstack import exceptions as sdk_exc +from openstackclient.common import exceptions as exc from senlinclient.osc.v1 import action as osc_action from senlinclient.tests.unit.osc.v1 import fakes @@ -155,3 +156,46 @@ class TestActionList(TestAction): columns, data = self.cmd.take_action(parsed_args) self.mock_client.actions.assert_called_with(**kwargs) self.assertEqual(self.columns, columns) + + +class TestActionShow(TestAction): + get_response = { + "action": "CLUSTER_DELETE", + "cause": "RPC Request", + "context": {}, + "created_at": "2015-06-27T05:09:43", + "depended_by": [], + "depends_on": [], + "end_time": 1423570000.0, + "id": "ffbb9175-d510-4bc1-b676-c6aba2a4ca81", + "inputs": {}, + "interval": -1, + "name": "cluster_delete_fcc9b635", + "outputs": {}, + "owner": 'null', + "start_time": 1423570000.0, + "status": "FAILED", + "status_reason": "Cluster action FAILED", + "target": "fcc9b635-52e3-490b-99f2-87b1640e4e89", + "timeout": 3600, + "updated_at": 'null'} + + def setUp(self): + super(TestActionShow, self).setUp() + self.cmd = osc_action.ShowAction(self.app, None) + self.mock_client.get_action = mock.Mock( + return_value=sdk_action.Action(None, self.get_response)) + + def test_action_show(self): + arglist = ['my_action'] + parsed_args = self.check_parser(self.cmd, arglist, []) + self.cmd.take_action(parsed_args) + self.mock_client.get_action.assert_called_with('my_action') + + def test_action_show_not_found(self): + arglist = ['my_action'] + parsed_args = self.check_parser(self.cmd, arglist, []) + self.mock_client.get_action.side_effect = sdk_exc.ResourceNotFound() + error = self.assertRaises(exc.CommandError, self.cmd.take_action, + parsed_args) + self.assertEqual('Action not found: my_action', str(error)) diff --git a/setup.cfg b/setup.cfg index ba1d74d..dda2b03 100644 --- a/setup.cfg +++ b/setup.cfg @@ -31,6 +31,7 @@ openstack.cli.extension = openstack.clustering.v1 = cluster_action_list = senlinclient.osc.v1.action:ListAction + cluster_action_show = senlinclient.osc.v1.action:ShowAction cluster_policy_binding_list = senlinclient.osc.v1.cluster_policy:ClusterPolicyList cluster_policy_binding_show = senlinclient.osc.v1.cluster_policy:ClusterPolicyShow cluster_policy_binding_update = senlinclient.osc.v1.cluster_policy:ClusterPolicyUpdate