From 60f3de47e36eebbcf4cde4655096e73d0dc24f3e Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Fri, 14 Feb 2014 17:52:01 -0500 Subject: [PATCH] add output-list and output-show This patch adds the "output-list" and "output-show" commands to heat. The first prints a table of available outputs to stdout, and the second prints a single output_value to stdout. All outputs are serialized to JSON. This patch includes tests for the new commands as well as updated documentation. Implements blueprint: stack-outputs-in-shell Change-Id: Iaade16d043b2c42d14f642fde17419eaa07d0ab8 Closes-Bug: 1258622 --- doc/source/man/heat.rst | 8 ++++++ heatclient/tests/test_shell.py | 45 ++++++++++++++++++++++++++++++++++ heatclient/v1/shell.py | 40 ++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) diff --git a/doc/source/man/heat.rst b/doc/source/man/heat.rst index 6624e57b..5da86af6 100644 --- a/doc/source/man/heat.rst +++ b/doc/source/man/heat.rst @@ -61,6 +61,14 @@ View stack information:: heat stack-show mystack +List stack outputs:: + + heat output-list + +Show the value of a single output:: + + heat output-show + List events:: heat event-list mystack diff --git a/heatclient/tests/test_shell.py b/heatclient/tests/test_shell.py index 11ef348c..cf5aebee 100644 --- a/heatclient/tests/test_shell.py +++ b/heatclient/tests/test_shell.py @@ -577,6 +577,51 @@ class ShellTestUserPass(ShellBase): abandon_resp = self.shell('stack-abandon teststack/1') self.assertEqual(abandoned_stack, jsonutils.loads(abandon_resp)) + def _output_fake_response(self): + self._script_keystone_client() + + resp_dict = {"stack": { + "id": "1", + "stack_name": "teststack", + "stack_status": 'CREATE_COMPLETE', + "creation_time": "2012-10-25T01:58:47Z", + "outputs": [ + { + "output_value": "value1", + "output_key": "output1", + "description": "test output 1", + }, + { + "output_value": ["output", "value", "2"], + "output_key": "output2", + "description": "test output 2", + }, + ], + "creation_time": "2012-10-25T01:58:47Z" + }} + + resp = fakes.FakeHTTPResponse( + 200, + 'OK', + {'content-type': 'application/json'}, + jsonutils.dumps(resp_dict)) + + http.HTTPClient.json_request( + 'GET', '/stacks/teststack/1').AndReturn((resp, resp_dict)) + + self.m.ReplayAll() + + def test_output_list(self): + self._output_fake_response() + list_text = self.shell('output-list teststack/1') + for r in ['output1', 'output2']: + self.assertRegexpMatches(list_text, r) + + def test_output_show(self): + self._output_fake_response() + list_text = self.shell('output-show teststack/1 output1') + self.assertRegexpMatches(list_text, 'value1') + def test_template_show_cfn(self): self._script_keystone_client() template_data = open(os.path.join(TEST_VAR_DIR, diff --git a/heatclient/v1/shell.py b/heatclient/v1/shell.py index 741f0216..53daa9b5 100644 --- a/heatclient/v1/shell.py +++ b/heatclient/v1/shell.py @@ -323,6 +323,46 @@ def do_stack_list(hc, args=None): utils.print_list(stacks, fields, sortby=3) +@utils.arg('id', metavar='', + help='Name or ID of stack to query.') +def do_output_list(hc, args): + '''Show available outputs.''' + try: + stack = hc.stacks.get(stack_id=args.id) + except exc.HTTPNotFound: + raise exc.CommandError('Stack not found: %s' % args.id) + else: + outputs = stack.to_dict()['outputs'] + fields = ['output_key', 'description'] + formatters = { + 'output_key': lambda x: x['output_key'], + 'description': lambda x: x['description'], + } + + utils.print_list(outputs, fields, formatters=formatters) + + +@utils.arg('id', metavar='', + help='Name or ID of stack to query.') +@utils.arg('output', metavar='', + help='Name of an output to display.') +def do_output_show(hc, args): + '''Show a specific stack output.''' + try: + stack = hc.stacks.get(stack_id=args.id) + except exc.HTTPNotFound: + raise exc.CommandError('Stack not found: %s' % args.id) + else: + for output in stack.to_dict().get('outputs', []): + if output['output_key'] == args.output: + value = output['output_value'] + break + else: + return + + print (jsonutils.dumps(value, indent=2)) + + def do_resource_type_list(hc, args={}): '''List the available resource types.''' kwargs = {}