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:
Seungju Baek 2023-08-22 00:39:41 +09:00 committed by Baek Seung Ju
parent 911cf7ddb1
commit c212f3f6af
7 changed files with 118 additions and 1 deletions

View File

@ -18,7 +18,7 @@ Stack Operations
.. autoclass:: openstack.orchestration.v1._proxy.Proxy
: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_template, stacks, validate_template, resources,
export_stack

View File

@ -240,6 +240,26 @@ class Proxy(proxy.Proxy):
obj = self._find(_stack.Stack, stack, ignore_missing=False)
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):
"""Get template used by a stack

View File

@ -192,6 +192,24 @@ class Stack(resource.Resource):
exceptions.raise_from_response(resp)
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(
self,
session,

View File

@ -80,3 +80,26 @@ class TestStack(base.BaseFunctionalTest):
def test_list(self):
names = [o.name for o in self.conn.orchestration.stacks()]
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)

View File

@ -150,6 +150,22 @@ class TestOrchestrationStack(TestOrchestrationProxy):
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):
self.verify_delete(self.proxy.delete_stack, stack.Stack, False)

View File

@ -340,3 +340,39 @@ class TestStack(base.TestCase):
FAKE_UPDATE_PREVIEW_RESPONSE['unchanged'], ret.unchanged
)
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)

View File

@ -0,0 +1,4 @@
---
features:
- |
Adds ``suspend_stack`` and ``resume_stack`` to support stack non-lifecycle operations.