Implemented heat 'stack suspend' and 'stack resume' function
Added suspend_stack function to support stack resources suspend. Added resume_stack function to support stack resources resume. Also implemented functional test and unit test code. Change-Id: Idf4befef149e945a419a3434886a8ba5c76481c6
This commit is contained in:
parent
911cf7ddb1
commit
c212f3f6af
@ -18,7 +18,7 @@ Stack Operations
|
|||||||
|
|
||||||
.. autoclass:: openstack.orchestration.v1._proxy.Proxy
|
.. autoclass:: openstack.orchestration.v1._proxy.Proxy
|
||||||
:noindex:
|
:noindex:
|
||||||
:members: create_stack, check_stack, update_stack, delete_stack, find_stack,
|
:members: create_stack, check_stack, update_stack, delete_stack, find_stack, suspend_stack, resume_stack,
|
||||||
get_stack, get_stack_environment, get_stack_files,
|
get_stack, get_stack_environment, get_stack_files,
|
||||||
get_stack_template, stacks, validate_template, resources,
|
get_stack_template, stacks, validate_template, resources,
|
||||||
export_stack
|
export_stack
|
||||||
|
@ -240,6 +240,26 @@ class Proxy(proxy.Proxy):
|
|||||||
obj = self._find(_stack.Stack, stack, ignore_missing=False)
|
obj = self._find(_stack.Stack, stack, ignore_missing=False)
|
||||||
return obj.export(self)
|
return obj.export(self)
|
||||||
|
|
||||||
|
def suspend_stack(self, stack):
|
||||||
|
"""Suspend a stack status
|
||||||
|
|
||||||
|
:param stack: The value can be either the ID of a stack or an instance
|
||||||
|
of :class:`~openstack.orchestration.v1.stack.Stack`.
|
||||||
|
:returns: ``None``
|
||||||
|
"""
|
||||||
|
res = self._get_resource(_stack.Stack, stack)
|
||||||
|
res.suspend(self)
|
||||||
|
|
||||||
|
def resume_stack(self, stack):
|
||||||
|
"""Resume a stack status
|
||||||
|
|
||||||
|
:param stack: The value can be either the ID of a stack or an instance
|
||||||
|
of :class:`~openstack.orchestration.v1.stack.Stack`.
|
||||||
|
:returns: ``None``
|
||||||
|
"""
|
||||||
|
res = self._get_resource(_stack.Stack, stack)
|
||||||
|
res.resume(self)
|
||||||
|
|
||||||
def get_stack_template(self, stack):
|
def get_stack_template(self, stack):
|
||||||
"""Get template used by a stack
|
"""Get template used by a stack
|
||||||
|
|
||||||
|
@ -192,6 +192,24 @@ class Stack(resource.Resource):
|
|||||||
exceptions.raise_from_response(resp)
|
exceptions.raise_from_response(resp)
|
||||||
return resp.json()
|
return resp.json()
|
||||||
|
|
||||||
|
def suspend(self, session):
|
||||||
|
"""Suspend a stack
|
||||||
|
|
||||||
|
:param session: The session to use for making this request
|
||||||
|
:returns: None
|
||||||
|
"""
|
||||||
|
body = {"suspend": None}
|
||||||
|
self._action(session, body)
|
||||||
|
|
||||||
|
def resume(self, session):
|
||||||
|
"""Resume a stack
|
||||||
|
|
||||||
|
:param session: The session to use for making this request
|
||||||
|
:returns: None
|
||||||
|
"""
|
||||||
|
body = {"resume": None}
|
||||||
|
self._action(session, body)
|
||||||
|
|
||||||
def fetch(
|
def fetch(
|
||||||
self,
|
self,
|
||||||
session,
|
session,
|
||||||
|
@ -80,3 +80,26 @@ class TestStack(base.BaseFunctionalTest):
|
|||||||
def test_list(self):
|
def test_list(self):
|
||||||
names = [o.name for o in self.conn.orchestration.stacks()]
|
names = [o.name for o in self.conn.orchestration.stacks()]
|
||||||
self.assertIn(self.NAME, names)
|
self.assertIn(self.NAME, names)
|
||||||
|
|
||||||
|
def test_suspend_resume(self):
|
||||||
|
# given
|
||||||
|
suspend_status = "SUSPEND_COMPLETE"
|
||||||
|
resume_status = "RESUME_COMPLETE"
|
||||||
|
|
||||||
|
# when
|
||||||
|
self.conn.orchestration.suspend_stack(self.stack)
|
||||||
|
sot = self.conn.orchestration.wait_for_status(
|
||||||
|
self.stack, suspend_status, wait=self._wait_for_timeout
|
||||||
|
)
|
||||||
|
|
||||||
|
# then
|
||||||
|
self.assertEqual(suspend_status, sot.status)
|
||||||
|
|
||||||
|
# when
|
||||||
|
self.conn.orchestration.resume_stack(self.stack)
|
||||||
|
sot = self.conn.orchestration.wait_for_status(
|
||||||
|
self.stack, resume_status, wait=self._wait_for_timeout
|
||||||
|
)
|
||||||
|
|
||||||
|
# then
|
||||||
|
self.assertEqual(resume_status, sot.status)
|
||||||
|
@ -150,6 +150,22 @@ class TestOrchestrationStack(TestOrchestrationProxy):
|
|||||||
expected_args=[self.proxy],
|
expected_args=[self.proxy],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_suspend_stack(self):
|
||||||
|
self._verify(
|
||||||
|
'openstack.orchestration.v1.stack.Stack.suspend',
|
||||||
|
self.proxy.suspend_stack,
|
||||||
|
method_args=['stack'],
|
||||||
|
expected_args=[self.proxy],
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_resume_stack(self):
|
||||||
|
self._verify(
|
||||||
|
'openstack.orchestration.v1.stack.Stack.resume',
|
||||||
|
self.proxy.resume_stack,
|
||||||
|
method_args=['stack'],
|
||||||
|
expected_args=[self.proxy],
|
||||||
|
)
|
||||||
|
|
||||||
def test_delete_stack(self):
|
def test_delete_stack(self):
|
||||||
self.verify_delete(self.proxy.delete_stack, stack.Stack, False)
|
self.verify_delete(self.proxy.delete_stack, stack.Stack, False)
|
||||||
|
|
||||||
|
@ -340,3 +340,39 @@ class TestStack(base.TestCase):
|
|||||||
FAKE_UPDATE_PREVIEW_RESPONSE['unchanged'], ret.unchanged
|
FAKE_UPDATE_PREVIEW_RESPONSE['unchanged'], ret.unchanged
|
||||||
)
|
)
|
||||||
self.assertEqual(FAKE_UPDATE_PREVIEW_RESPONSE['updated'], ret.updated)
|
self.assertEqual(FAKE_UPDATE_PREVIEW_RESPONSE['updated'], ret.updated)
|
||||||
|
|
||||||
|
def test_suspend(self):
|
||||||
|
sess = mock.Mock()
|
||||||
|
|
||||||
|
mock_response = mock.Mock()
|
||||||
|
mock_response.status_code = 200
|
||||||
|
mock_response.headers = {}
|
||||||
|
mock_response.json.return_value = {}
|
||||||
|
sess.post = mock.Mock(return_value=mock_response)
|
||||||
|
url = "stacks/%s/actions" % FAKE_ID
|
||||||
|
body = {"suspend": None}
|
||||||
|
sot = stack.Stack(**FAKE)
|
||||||
|
|
||||||
|
res = sot.suspend(sess)
|
||||||
|
|
||||||
|
self.assertIsNone(res)
|
||||||
|
sess.post.assert_called_with(url, json=body, microversion=None)
|
||||||
|
|
||||||
|
def test_resume(self):
|
||||||
|
sess = mock.Mock()
|
||||||
|
|
||||||
|
mock_response = mock.Mock()
|
||||||
|
mock_response.status_code = 200
|
||||||
|
mock_response.headers = {}
|
||||||
|
mock_response.json.return_value = {}
|
||||||
|
sess.post = mock.Mock(return_value=mock_response)
|
||||||
|
url = "stacks/%s/actions" % FAKE_ID
|
||||||
|
|
||||||
|
body = {"resume": None}
|
||||||
|
|
||||||
|
sot = stack.Stack(**FAKE)
|
||||||
|
|
||||||
|
res = sot.resume(sess)
|
||||||
|
|
||||||
|
self.assertIsNone(res)
|
||||||
|
sess.post.assert_called_with(url, json=body, microversion=None)
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds ``suspend_stack`` and ``resume_stack`` to support stack non-lifecycle operations.
|
Loading…
x
Reference in New Issue
Block a user