Make get_stack fetch a single full stack

There is a convention in shade for get_<entity> calls to do a
list_<entities> with no server filtering then do a client-side filter
to return a single result. This approach is not appropriate for Heat
since the stacks.list call returns significantly less detail than the
stacks.get call.

A user calling get_stack will almost certainly be wanting the extra
detail provided by the proper stacks.get (for example, the stack
outputs).

This change switches to using stacks.get for the get_stack
implementation. It replaces the search_stacks call with a local
function that returns a 'list' of one full stack object.

Change-Id: I5d326d489f806709252a22360f3dbd8011fdb9c7
This commit is contained in:
Steve Baker 2016-03-14 11:20:57 +13:00
parent ee88b23113
commit ebec668530
3 changed files with 17 additions and 2 deletions

View File

@ -735,3 +735,8 @@ class StackCreate(task_manager.Task):
class StackDelete(task_manager.Task): class StackDelete(task_manager.Task):
def main(self, client): def main(self, client):
return client.heat_client.stacks.delete(self.args['id']) return client.heat_client.stacks.delete(self.args['id'])
class StackGet(task_manager.Task):
def main(self, client):
return client.heat_client.stacks.get(**self.args)

View File

@ -1669,8 +1669,18 @@ class OpenStackCloud(object):
:raises: ``OpenStackCloudException`` if something goes wrong during the :raises: ``OpenStackCloudException`` if something goes wrong during the
openstack API call or if multiple matches are found. openstack API call or if multiple matches are found.
""" """
def search_one_stack(name_or_id=None, filters=None):
# stack names are mandatory and enforced unique in the project
# so a StackGet can always be used for name or ID.
with _utils.shade_exceptions("Error fetching stack"):
stacks = [self.manager.submitTask(
_tasks.StackGet(stack_id=name_or_id))]
nstacks = _utils.normalize_stacks(stacks)
return _utils._filter_list(nstacks, name_or_id, filters)
return _utils._get_entity( return _utils._get_entity(
self.search_stacks, name_or_id, filters) search_one_stack, name_or_id, filters)
def create_keypair(self, name, public_key): def create_keypair(self, name, public_key):
"""Create a new keypair. """Create a new keypair.

View File

@ -149,7 +149,7 @@ class TestStack(base.TestCase):
@mock.patch.object(shade.OpenStackCloud, 'heat_client') @mock.patch.object(shade.OpenStackCloud, 'heat_client')
def test_get_stack(self, mock_heat): def test_get_stack(self, mock_heat):
stack = fakes.FakeStack('azerty', 'stack',) stack = fakes.FakeStack('azerty', 'stack',)
mock_heat.stacks.list.return_value = [stack] mock_heat.stacks.get.return_value = stack
res = self.cloud.get_stack('stack') res = self.cloud.get_stack('stack')
self.assertIsNotNone(res) self.assertIsNotNone(res)
self.assertEqual(stack.stack_name, res['stack_name']) self.assertEqual(stack.stack_name, res['stack_name'])