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:
parent
b1339abcd1
commit
01b5878129
@ -431,6 +431,13 @@ cancel_update:
|
|||||||
in: body
|
in: body
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
cancel_without_rollback:
|
||||||
|
description: |
|
||||||
|
Specify the ``cancel_without_rollback`` action in
|
||||||
|
the request body..
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
capabilities:
|
capabilities:
|
||||||
description: |
|
description: |
|
||||||
List of stack capabilities for stack.
|
List of stack capabilities for stack.
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"cancel_without_rollback": null
|
||||||
|
}
|
@ -154,6 +154,55 @@ Response Example
|
|||||||
This operation does not return a response body.
|
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
|
Check stack resources
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
|
@ -30,9 +30,11 @@ class ActionController(object):
|
|||||||
REQUEST_SCOPE = 'actions'
|
REQUEST_SCOPE = 'actions'
|
||||||
|
|
||||||
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):
|
def __init__(self, options):
|
||||||
@ -64,7 +66,11 @@ class ActionController(object):
|
|||||||
elif ac == self.CHECK:
|
elif ac == self.CHECK:
|
||||||
self.rpc_client.stack_check(req.context, identity)
|
self.rpc_client.stack_check(req.context, identity)
|
||||||
elif ac == self.CANCEL_UPDATE:
|
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:
|
else:
|
||||||
raise exc.HTTPInternalServerError(_("Unexpected action %s") % ac)
|
raise exc.HTTPInternalServerError(_("Unexpected action %s") % ac)
|
||||||
|
|
||||||
|
@ -1151,10 +1151,12 @@ class EngineService(service.ServiceBase):
|
|||||||
db_stack = self._get_stack(cnxt, stack_identity)
|
db_stack = self._get_stack(cnxt, stack_identity)
|
||||||
|
|
||||||
current_stack = parser.Stack.load(cnxt, stack=db_stack)
|
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,)
|
allowed_actions = (current_stack.UPDATE,)
|
||||||
else: # Cancelled by parent stack
|
else:
|
||||||
allowed_actions = (current_stack.UPDATE, current_stack.CREATE)
|
allowed_actions = (current_stack.UPDATE, current_stack.CREATE)
|
||||||
|
|
||||||
if not (current_stack.status == current_stack.IN_PROGRESS and
|
if not (current_stack.status == current_stack.IN_PROGRESS and
|
||||||
current_stack.action in allowed_actions):
|
current_stack.action in allowed_actions):
|
||||||
state = '_'.join(current_stack.state)
|
state = '_'.join(current_stack.state)
|
||||||
|
@ -88,30 +88,35 @@ class ActionControllerTest(tools.ControllerTest, common.HeatTestCase):
|
|||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
self.m.VerifyAll()
|
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)
|
self._mock_enforce_setup(mock_enforce, 'action', True)
|
||||||
stack_identity = identifier.HeatIdentifier(self.tenant,
|
stack_identity = identifier.HeatIdentifier(self.tenant,
|
||||||
'wordpress', '1')
|
'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',
|
req = self._post(stack_identity._tenant_path() + '/actions',
|
||||||
data=json.dumps(body))
|
data=json.dumps(body))
|
||||||
|
|
||||||
self.m.StubOutWithMock(rpc_client.EngineClient, 'call')
|
client = self.patchobject(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()
|
|
||||||
|
|
||||||
result = self.controller.action(req, tenant_id=self.tenant,
|
result = self.controller.action(req, tenant_id=self.tenant,
|
||||||
stack_name=stack_identity.stack_name,
|
stack_name=stack_identity.stack_name,
|
||||||
stack_id=stack_identity.stack_id,
|
stack_id=stack_identity.stack_id,
|
||||||
body=body)
|
body=body)
|
||||||
self.assertIsNone(result)
|
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):
|
def test_action_badaction(self, mock_enforce):
|
||||||
self._mock_enforce_setup(mock_enforce, 'action', True)
|
self._mock_enforce_setup(mock_enforce, 'action', True)
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
Adds REST api support to cancel a stack create/update without rollback.
|
Loading…
Reference in New Issue
Block a user