diff --git a/heatclient/osc/v1/stack.py b/heatclient/osc/v1/stack.py index d0b97e09..e4148d1f 100644 --- a/heatclient/osc/v1/stack.py +++ b/heatclient/osc/v1/stack.py @@ -1220,11 +1220,17 @@ class CancelStack(StackActionBase): log = logging.getLogger(__name__ + '.CancelStack') def get_parser(self, prog_name): - return self._get_parser( + parser = self._get_parser( prog_name, _('Stack(s) to cancel (name or ID)'), - _('Wait for check to complete') + _('Wait for cancel to complete') ) + parser.add_argument( + '--no-rollback', + action='store_true', + help=_('Cancel without rollback') + ) + return parser def take_action(self, parsed_args): self.log.debug("take_action(%s)", parsed_args) @@ -1237,7 +1243,10 @@ class CancelStack(StackActionBase): 'Updated Time' ] heat_client = self.app.client_manager.orchestration - + if parsed_args.no_rollback: + action = heat_client.actions.cancel_without_rollback + else: + action = heat_client.actions.cancel_update for stack in parsed_args.stack: try: data = heat_client.stacks.get(stack_id=stack) @@ -1246,11 +1255,12 @@ class CancelStack(StackActionBase): status = getattr(data, 'stack_status').lower() if status == 'update_in_progress': + data = _stack_action( stack, parsed_args, heat_client, - heat_client.actions.cancel_update + action ) 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 159056a7..ebe53290 100644 --- a/heatclient/tests/unit/osc/v1/test_stack.py +++ b/heatclient/tests/unit/osc/v1/test_stack.py @@ -1221,6 +1221,18 @@ class TestStackCancel(_TestStackCheckBase, TestStack): def test_stack_cancel(self): self._test_stack_action(2) + def test_stack_cancel_no_rollback(self): + self.action = self.mock_client.actions.cancel_without_rollback + arglist = ['my_stack', '--no-rollback'] + parsed_args = self.check_parser(self.cmd, arglist, []) + columns, rows = self.cmd.take_action(parsed_args) + self.action.assert_called_once_with('my_stack') + self.mock_client.stacks.get.assert_called_with('my_stack') + self.assertEqual(2, + self.mock_client.stacks.get.call_count) + self.assertEqual(self.columns, columns) + self.assertEqual(1, len(rows)) + def test_stack_cancel_multi(self): self._test_stack_action_multi(4) diff --git a/heatclient/tests/unit/test_actions.py b/heatclient/tests/unit/test_actions.py index 93b6e491..512d5665 100644 --- a/heatclient/tests/unit/test_actions.py +++ b/heatclient/tests/unit/test_actions.py @@ -98,6 +98,15 @@ class ActionManagerTest(testtools.TestCase): manager = self._base_test(expect_args, expect_kwargs) manager.cancel_update(**fields) + def test_cancel_without_rollback(self): + fields = {'stack_id': 'teststack%2Fabcd1234'} + expect_args = ('POST', + '/stacks/teststack%2Fabcd1234/actions') + expect_kwargs = {'data': {'cancel_without_rollback': None}} + + manager = self._base_test(expect_args, expect_kwargs) + manager.cancel_without_rollback(**fields) + def test_check(self): fields = {'stack_id': 'teststack%2Fabcd1234'} expect_args = ('POST', diff --git a/heatclient/v1/actions.py b/heatclient/v1/actions.py index 0331866b..81857e2e 100644 --- a/heatclient/v1/actions.py +++ b/heatclient/v1/actions.py @@ -48,6 +48,11 @@ class ActionManager(stacks.StackChildManager): body = {'cancel_update': None} self.client.post('/stacks/%s/actions' % stack_id, data=body) + def cancel_without_rollback(self, stack_id): + """Cancel running update of a stack.""" + body = {'cancel_without_rollback': None} + self.client.post('/stacks/%s/actions' % stack_id, data=body) + def check(self, stack_id): """Check a stack.""" body = {'check': None}