summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Baker <sbaker@redhat.com>2016-02-15 13:12:19 +1300
committerSergey Kraynev <skraynev@mirantis.com>2016-02-26 09:51:55 -0500
commitd00903ad9389a45ede398663f7c18337bbbda4d8 (patch)
tree65c9d56151d640d8c87755aa6b181baf8e689ae3
parent0a7f8bf1d6c802db673c0956f30a41b29626196f (diff)
downloadpython-heatclient-d00903ad9389a45ede398663f7c18337bbbda4d8.tar.gz
Use poll_for_events for "openstack stack <action>"
These are treated like the poll_for_events for stack update, except for the cancel action which stops polling on any COMPLETE or FAILED state. Change-Id: I3723bde4f26abb12674d15df65764fb6d8a67a56 Blueprint: heat-support-python-openstackclient
-rw-r--r--heatclient/osc/v1/stack.py48
-rw-r--r--heatclient/tests/unit/osc/v1/test_stack.py35
2 files changed, 50 insertions, 33 deletions
diff --git a/heatclient/osc/v1/stack.py b/heatclient/osc/v1/stack.py
index 83d4aa2..2e16a19 100644
--- a/heatclient/osc/v1/stack.py
+++ b/heatclient/osc/v1/stack.py
@@ -940,19 +940,18 @@ class StackActionBase(lister.Lister):
)
return parser
- def _take_action(self, parsed_args, action, good_status, bad_status):
+ def _take_action(self, parsed_args, action, action_name=None):
self.log.debug("take_action(%s)", parsed_args)
heat_client = self.app.client_manager.orchestration
return _stacks_action(
parsed_args,
heat_client,
action,
- good_status,
- bad_status
+ action_name
)
-def _stacks_action(parsed_args, heat_client, action, good_status, bad_status):
+def _stacks_action(parsed_args, heat_client, action, action_name=None):
rows = []
columns = [
'ID',
@@ -963,13 +962,20 @@ def _stacks_action(parsed_args, heat_client, action, good_status, bad_status):
]
for stack in parsed_args.stack:
data = _stack_action(stack, parsed_args, heat_client, action,
- good_status, bad_status)
+ action_name)
rows += [utils.get_dict_properties(data.to_dict(), columns)]
return (columns, rows)
-def _stack_action(stack, parsed_args, heat_client, action,
- good_status, bad_status):
+def _stack_action(stack, parsed_args, heat_client, action, action_name=None):
+ if parsed_args.wait:
+ # find the last event to use as the marker
+ events = event_utils.get_events(heat_client,
+ stack_id=stack,
+ event_args={'sort_dir': 'desc',
+ 'limit': 1})
+ marker = events[0].id if events else None
+
try:
action(stack)
except heat_exc.HTTPNotFound:
@@ -977,12 +983,15 @@ def _stack_action(stack, parsed_args, heat_client, action,
raise exc.CommandError(msg)
if parsed_args.wait:
- if not utils.wait_for_status(heat_client.stacks.get, stack,
- status_field='stack_status',
- success_status=good_status,
- error_status=bad_status):
- err = _("Error waiting for status from stack %s") % stack
- raise exc.CommandError(err)
+ s = heat_client.stacks.get(stack)
+ stack_status, msg = event_utils.poll_for_events(
+ heat_client, s.stack_name, action=action_name, marker=marker)
+ if action_name:
+ if stack_status == '%s_FAILED' % action_name:
+ raise exc.CommandError(msg)
+ else:
+ if stack_status.endswith('_FAILED'):
+ raise exc.CommandError(msg)
return heat_client.stacks.get(stack)
@@ -1003,8 +1012,7 @@ class SuspendStack(StackActionBase):
return self._take_action(
parsed_args,
self.app.client_manager.orchestration.actions.suspend,
- ['suspend_complete'],
- ['suspend_failed']
+ 'SUSPEND'
)
@@ -1024,8 +1032,7 @@ class ResumeStack(StackActionBase):
return self._take_action(
parsed_args,
self.app.client_manager.orchestration.actions.resume,
- ['resume_complete'],
- ['resume_failed']
+ 'RESUME'
)
@@ -1045,8 +1052,7 @@ class CheckStack(StackActionBase):
return self._take_action(
parsed_args,
self.app.client_manager.orchestration.actions.check,
- ['check_complete'],
- ['check_failed']
+ 'CHECK'
)
@@ -1090,9 +1096,7 @@ class CancelStack(StackActionBase):
stack,
parsed_args,
heat_client,
- heat_client.actions.cancel_update,
- ['cancel_update_complete'],
- ['cancel_update_failed']
+ heat_client.actions.cancel_update
)
rows += [utils.get_dict_properties(data.to_dict(), columns)]
else:
diff --git a/heatclient/tests/unit/osc/v1/test_stack.py b/heatclient/tests/unit/osc/v1/test_stack.py
index f285f56..ecfacf6 100644
--- a/heatclient/tests/unit/osc/v1/test_stack.py
+++ b/heatclient/tests/unit/osc/v1/test_stack.py
@@ -935,11 +935,12 @@ class _TestStackCheckBase(object):
columns = ['ID', 'Stack Name', 'Stack Status', 'Creation Time',
'Updated Time']
- def _setUp(self, cmd, action):
+ def _setUp(self, cmd, action, action_name=None):
self.cmd = cmd
self.action = action
self.mock_client.stacks.get = mock.Mock(
return_value=self.stack)
+ self.action_name = action_name
def _test_stack_action(self, get_call_count=1):
arglist = ['my_stack']
@@ -964,10 +965,14 @@ class _TestStackCheckBase(object):
self.assertEqual(self.columns, columns)
self.assertEqual(2, len(rows))
- @mock.patch('openstackclient.common.utils.wait_for_status',
- return_value=True)
- def _test_stack_action_wait(self, mock_wait):
+ @mock.patch('heatclient.common.event_utils.poll_for_events')
+ @mock.patch('heatclient.common.event_utils.get_events', return_value=[])
+ def _test_stack_action_wait(self, ge, mock_poll):
arglist = ['my_stack', '--wait']
+ mock_poll.return_value = (
+ '%s_COMPLETE' % self.action_name,
+ 'Stack my_stack %s_COMPLETE' % self.action_name
+ )
parsed_args = self.check_parser(self.cmd, arglist, [])
columns, rows = self.cmd.take_action(parsed_args)
self.action.assert_called_with('my_stack')
@@ -975,10 +980,14 @@ class _TestStackCheckBase(object):
self.assertEqual(self.columns, columns)
self.assertEqual(1, len(rows))
- @mock.patch('openstackclient.common.utils.wait_for_status',
- return_value=False)
- def _test_stack_action_wait_error(self, mock_wait):
+ @mock.patch('heatclient.common.event_utils.poll_for_events')
+ @mock.patch('heatclient.common.event_utils.get_events', return_value=[])
+ def _test_stack_action_wait_error(self, ge, mock_poll):
arglist = ['my_stack', '--wait']
+ mock_poll.return_value = (
+ '%s_FAILED' % self.action_name,
+ 'Error waiting for status from stack my_stack'
+ )
parsed_args = self.check_parser(self.cmd, arglist, [])
error = self.assertRaises(exc.CommandError,
self.cmd.take_action,
@@ -1004,7 +1013,8 @@ class TestStackSuspend(_TestStackCheckBase, TestStack):
self.mock_client.actions.suspend = mock.Mock()
self._setUp(
stack.SuspendStack(self.app, None),
- self.mock_client.actions.suspend
+ self.mock_client.actions.suspend,
+ 'SUSPEND'
)
def test_stack_suspend(self):
@@ -1030,7 +1040,8 @@ class TestStackResume(_TestStackCheckBase, TestStack):
self.mock_client.actions.resume = mock.Mock()
self._setUp(
stack.ResumeStack(self.app, None),
- self.mock_client.actions.resume
+ self.mock_client.actions.resume,
+ 'RESUME'
)
def test_stack_resume(self):
@@ -1064,7 +1075,8 @@ class TestStackCancel(_TestStackCheckBase, TestStack):
self.mock_client.actions.cancel_update = mock.Mock()
self._setUp(
stack.CancelStack(self.app, None),
- self.mock_client.actions.cancel_update
+ self.mock_client.actions.cancel_update,
+ 'ROLLBACK'
)
self.mock_client.stacks.get = mock.Mock(
return_value=self.stack_update_in_progress)
@@ -1102,7 +1114,8 @@ class TestStackCheck(_TestStackCheckBase, TestStack):
self.mock_client.actions.check = mock.Mock()
self._setUp(
stack.CheckStack(self.app, None),
- self.mock_client.actions.check
+ self.mock_client.actions.check,
+ 'CHECK'
)
def test_stack_check(self):