OpenstackClient plugin for template show

This change implements the 'openstack stack template show' command.

Blueprint: heat-support-python-openstackclient

Change-Id: I4a832435e692fb92a169d01a9e95c5c083c49531
This commit is contained in:
Bryan Jones 2016-01-14 16:43:58 +00:00
parent 270d0178f8
commit f6373978e5
4 changed files with 152 additions and 0 deletions

View File

@ -807,3 +807,31 @@ class OutputListStack(lister.Lister):
columns, columns,
(utils.get_dict_properties(s, columns) for s in outputs) (utils.get_dict_properties(s, columns) for s in outputs)
) )
class TemplateShowStack(format_utils.YamlFormat):
"""Display stack template."""
log = logging.getLogger(__name__ + '.TemplateShowStack')
def get_parser(self, prog_name):
parser = super(TemplateShowStack, self).get_parser(prog_name)
parser.add_argument(
'stack',
metavar='<NAME or ID>',
help=_('Name or ID of stack to query')
)
return parser
def take_action(self, parsed_args):
self.log.debug('take_action(%s)', parsed_args)
client = self.app.client_manager.orchestration
try:
template = client.stacks.template(stack_id=parsed_args.stack)
except heat_exc.HTTPNotFound:
msg = _('Stack not found: %s') % parsed_args.stack
raise exc.CommandError(msg)
return self.dict2columns(template)

View File

@ -0,0 +1,78 @@
#
# Copyright 2016 IBM Corp.
#
# 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.
FULL_TEMPLATE = '''
heat_template_version: 2016-04-08
description: a template
parameter_groups:
- label: param_group_1
description: parameter group 1
parameters:
- param1
- param2
- label: param_group_2
description: parameter group 2
parameters:
- param3
parameters:
param1:
type: string
label: parameter 5
description: parameter 5
default: foo
hidden: false
constraints:
- allowed_values: ['foo', 'bar', 'bax']
param2:
type: number
default: 0
constraints:
- range: {min: 0, max: 10}
description: must be betwen 0 and 10
param3:
type: boolean
resources:
resource1:
type: OS::Heat::None
properties:
prop1: { get_param: param1 }
prop2: { get_param: param2 }
prop3: value
resource2:
type: OS::Heat::None
properties:
prop1: { get_param: param3 }
depends_on: resource1
outputs:
output1:
description: resource 1 prop 3
value: { get_attr: [resource1, prop3] }
output2:
description: resource 2 prop 1
value: { get_attr: [resource2, prop1] }
'''
SHORT_TEMPLATE = '''
heat_template_version: 2016-04-08
resources:
res1:
type: OS::Heat::None
'''

View File

@ -16,12 +16,15 @@ import io
import mock import mock
import six import six
import testscenarios import testscenarios
import yaml
from openstackclient.common import exceptions as exc from openstackclient.common import exceptions as exc
from openstackclient.common import utils from openstackclient.common import utils
from heatclient.common import template_format
from heatclient import exc as heat_exc from heatclient import exc as heat_exc
from heatclient.osc.v1 import stack from heatclient.osc.v1 import stack
from heatclient.tests import inline_templates
from heatclient.tests.unit.osc.v1 import fakes as orchestration_fakes from heatclient.tests.unit.osc.v1 import fakes as orchestration_fakes
from heatclient.v1 import stacks from heatclient.v1 import stacks
@ -757,3 +760,45 @@ class TestStackOutputList(TestStack):
error = self.assertRaises(exc.CommandError, error = self.assertRaises(exc.CommandError,
self.cmd.take_action, parsed_args) self.cmd.take_action, parsed_args)
self.assertEqual('Stack not found: my_stack', str(error)) self.assertEqual('Stack not found: my_stack', str(error))
class TestStackTemplateShow(TestStack):
fields = ['heat_template_version', 'description', 'parameter_groups',
'parameters', 'resources', 'outputs']
def setUp(self):
super(TestStackTemplateShow, self).setUp()
self.cmd = stack.TemplateShowStack(self.app, None)
def test_stack_template_show_full_template(self):
arglist = ['my_stack']
self.stack_client.template = mock.MagicMock(
return_value=yaml.load(inline_templates.FULL_TEMPLATE,
Loader=template_format.yaml_loader))
parsed_args = self.check_parser(self.cmd, arglist, [])
columns, outputs = self.cmd.take_action(parsed_args)
for f in self.fields:
self.assertIn(f, columns)
def test_stack_template_show_short_template(self):
arglist = ['my_stack']
self.stack_client.template = mock.MagicMock(
return_value=yaml.load(inline_templates.SHORT_TEMPLATE,
Loader=template_format.yaml_loader))
parsed_args = self.check_parser(self.cmd, arglist, [])
columns, outputs = self.cmd.take_action(parsed_args)
for f in ['heat_template_version', 'resources']:
self.assertIn(f, columns)
def test_stack_template_show_not_found(self):
arglist = ['my_stack']
self.stack_client.template = mock.MagicMock(
side_effect=heat_exc.HTTPNotFound)
parsed_args = self.check_parser(self.cmd, arglist, [])
self.assertRaises(exc.CommandError, self.cmd.take_action, parsed_args)

View File

@ -45,6 +45,7 @@ openstack.orchestration.v1 =
stack_resource_metadata = heatclient.osc.v1.resources:ResourceMetadata stack_resource_metadata = heatclient.osc.v1.resources:ResourceMetadata
stack_show = heatclient.osc.v1.stack:ShowStack stack_show = heatclient.osc.v1.stack:ShowStack
stack_snapshot_list = heatclient.osc.v1.snapshot:ListSnapshot stack_snapshot_list = heatclient.osc.v1.snapshot:ListSnapshot
stack_template_show = heatclient.osc.v1.stack:TemplateShowStack
stack_update = heatclient.osc.v1.stack:UpdateStack stack_update = heatclient.osc.v1.stack:UpdateStack
[global] [global]