From ebec66853033e0e953055e0a4e8fb906e7092e66 Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Mon, 14 Mar 2016 11:20:57 +1300 Subject: [PATCH] Make get_stack fetch a single full stack There is a convention in shade for get_ calls to do a list_ 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 --- shade/_tasks.py | 5 +++++ shade/openstackcloud.py | 12 +++++++++++- shade/tests/unit/test_stack.py | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/shade/_tasks.py b/shade/_tasks.py index 014cc5c69..9f72b57cc 100644 --- a/shade/_tasks.py +++ b/shade/_tasks.py @@ -735,3 +735,8 @@ class StackCreate(task_manager.Task): class StackDelete(task_manager.Task): def main(self, client): 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) diff --git a/shade/openstackcloud.py b/shade/openstackcloud.py index bf644ffcc..8c8582aeb 100644 --- a/shade/openstackcloud.py +++ b/shade/openstackcloud.py @@ -1669,8 +1669,18 @@ class OpenStackCloud(object): :raises: ``OpenStackCloudException`` if something goes wrong during the 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( - self.search_stacks, name_or_id, filters) + search_one_stack, name_or_id, filters) def create_keypair(self, name, public_key): """Create a new keypair. diff --git a/shade/tests/unit/test_stack.py b/shade/tests/unit/test_stack.py index f40ab72d0..e2e1a013c 100644 --- a/shade/tests/unit/test_stack.py +++ b/shade/tests/unit/test_stack.py @@ -149,7 +149,7 @@ class TestStack(base.TestCase): @mock.patch.object(shade.OpenStackCloud, 'heat_client') def test_get_stack(self, mock_heat): 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') self.assertIsNotNone(res) self.assertEqual(stack.stack_name, res['stack_name'])