Add REST api support for cancel without rollback

We already have REST api support for cancelling a
UPDATE_IN_PROGRESS stack with rollback. This adds a
new action 'cancel_without_rollback' to allow for
canceling a create/update in_progress stack without
rollback.

APIImpact

Change-Id: I6c6ffa0502ab8745cfb2f9c5ef263f1e02dfc4ca
Closes-Bug: #1709041
This commit is contained in:
rabi 2017-08-07 15:05:50 +05:30
parent b1339abcd1
commit 01b5878129
7 changed files with 93 additions and 18 deletions

View File

@ -431,6 +431,13 @@ cancel_update:
in: body
required: true
type: string
cancel_without_rollback:
description: |
Specify the ``cancel_without_rollback`` action in
the request body..
in: body
required: true
type: string
capabilities:
description: |
List of stack capabilities for stack.

View File

@ -0,0 +1,3 @@
{
"cancel_without_rollback": null
}

View File

@ -154,6 +154,55 @@ Response Example
This operation does not return a response body.
Cancel stack create/update without rollback
===========================================
.. rest_method:: POST /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/actions
Cancels a currently running create/update of a stack without rollback.
Response Codes
--------------
.. rest_status_code:: success status.yaml
- 200
.. rest_status_code:: error status.yaml
- 400
- 401
- 404
Request Parameters
------------------
.. rest_parameters:: parameters.yaml
- tenant_id: tenant_id
- stack_name: stack_name_url
- stack_id: stack_id_url
- cancel_without_rollback: cancel_without_rollback
Request Example
---------------
.. literalinclude:: samples/stack-action-cancel-without-rollback-request.json
:language: javascript
Response Parameters
-------------------
.. rest_parameters:: parameters.yaml
- X-Openstack-Request-Id: request_id
Response Example
----------------
This operation does not return a response body.
Check stack resources
=====================

View File

@ -30,9 +30,11 @@ class ActionController(object):
REQUEST_SCOPE = 'actions'
ACTIONS = (
SUSPEND, RESUME, CHECK, CANCEL_UPDATE
SUSPEND, RESUME, CHECK,
CANCEL_UPDATE, CANCEL_WITHOUT_ROLLBACK
) = (
'suspend', 'resume', 'check', 'cancel_update'
'suspend', 'resume', 'check',
'cancel_update', 'cancel_without_rollback'
)
def __init__(self, options):
@ -64,7 +66,11 @@ class ActionController(object):
elif ac == self.CHECK:
self.rpc_client.stack_check(req.context, identity)
elif ac == self.CANCEL_UPDATE:
self.rpc_client.stack_cancel_update(req.context, identity)
self.rpc_client.stack_cancel_update(req.context, identity,
cancel_with_rollback=True)
elif ac == self.CANCEL_WITHOUT_ROLLBACK:
self.rpc_client.stack_cancel_update(req.context, identity,
cancel_with_rollback=False)
else:
raise exc.HTTPInternalServerError(_("Unexpected action %s") % ac)

View File

@ -1151,10 +1151,12 @@ class EngineService(service.ServiceBase):
db_stack = self._get_stack(cnxt, stack_identity)
current_stack = parser.Stack.load(cnxt, stack=db_stack)
if cancel_with_rollback: # Commanded by user
if cancel_with_rollback:
allowed_actions = (current_stack.UPDATE,)
else: # Cancelled by parent stack
else:
allowed_actions = (current_stack.UPDATE, current_stack.CREATE)
if not (current_stack.status == current_stack.IN_PROGRESS and
current_stack.action in allowed_actions):
state = '_'.join(current_stack.state)

View File

@ -88,30 +88,35 @@ class ActionControllerTest(tools.ControllerTest, common.HeatTestCase):
self.assertIsNone(result)
self.m.VerifyAll()
def test_action_cancel_update(self, mock_enforce):
def _test_action_cancel_update(self, mock_enforce, with_rollback=True):
self._mock_enforce_setup(mock_enforce, 'action', True)
stack_identity = identifier.HeatIdentifier(self.tenant,
'wordpress', '1')
body = {'cancel_update': None}
if with_rollback:
body = {'cancel_update': None}
else:
body = {'cancel_without_rollback': None}
req = self._post(stack_identity._tenant_path() + '/actions',
data=json.dumps(body))
self.m.StubOutWithMock(rpc_client.EngineClient, 'call')
rpc_client.EngineClient.call(
req.context,
('stack_cancel_update',
{'stack_identity': stack_identity,
'cancel_with_rollback': True}),
version='1.14'
).AndReturn(None)
self.m.ReplayAll()
client = self.patchobject(rpc_client.EngineClient, 'call')
result = self.controller.action(req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id,
body=body)
self.assertIsNone(result)
self.m.VerifyAll()
client.assert_called_with(
req.context,
('stack_cancel_update',
{'stack_identity': stack_identity,
'cancel_with_rollback': with_rollback}),
version='1.14')
def test_action_cancel_update(self, mock_enforce):
self._test_action_cancel_update(mock_enforce)
def test_action_cancel_without_rollback(self, mock_enforce):
self._test_action_cancel_update(mock_enforce, False)
def test_action_badaction(self, mock_enforce):
self._mock_enforce_setup(mock_enforce, 'action', True)

View File

@ -0,0 +1,3 @@
---
features:
Adds REST api support to cancel a stack create/update without rollback.