Merge "Implement stack export in openstacksdk"

This commit is contained in:
Zuul 2023-09-05 12:14:18 +00:00 committed by Gerrit Code Review
commit e31f54551b
6 changed files with 83 additions and 1 deletions

View File

@ -20,7 +20,8 @@ Stack Operations
:noindex: :noindex:
:members: create_stack, check_stack, update_stack, delete_stack, find_stack, :members: create_stack, check_stack, update_stack, delete_stack, find_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
Software Configuration Operations Software Configuration Operations
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -24,6 +24,9 @@ from openstack import proxy
from openstack import resource from openstack import resource
# TODO(rladntjr4): Some of these methods support lookup by ID, while
# others support lookup by ID or name. We should choose one and use
# it consistently.
class Proxy(proxy.Proxy): class Proxy(proxy.Proxy):
_resource_registry = { _resource_registry = {
"resource": _resource.Resource, "resource": _resource.Resource,
@ -222,6 +225,21 @@ class Proxy(proxy.Proxy):
res = self._get_resource(_stack.Stack, stack) res = self._get_resource(_stack.Stack, stack)
return res.abandon(self) return res.abandon(self)
def export_stack(self, stack):
"""Get the stack data in JSON format
:param stack: The value can be the ID or a name or
an instance of :class:`~openstack.orchestration.v1.stack.Stack`
:returns: A dictionary containing the stack data.
:raises: :class:`~openstack.exceptions.ResourceNotFound`
when no resource can be found.
"""
if isinstance(stack, _stack.Stack):
obj = stack
else:
obj = self._find(_stack.Stack, stack, ignore_missing=False)
return obj.export(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

View File

@ -179,6 +179,19 @@ class Stack(resource.Resource):
resp = session.delete(url) resp = session.delete(url)
return resp.json() return resp.json()
def export(self, session):
"""Export a stack data
:param session: The session to use for making this request.
:return: A dictionary containing the stack data.
"""
url = utils.urljoin(
self.base_path, self.name, self._get_id(self), 'export'
)
resp = session.get(url)
exceptions.raise_from_response(resp)
return resp.json()
def fetch( def fetch(
self, self,
session, session,

View File

@ -121,6 +121,35 @@ class TestOrchestrationStack(TestOrchestrationProxy):
expected_args=[self.proxy], expected_args=[self.proxy],
) )
@mock.patch.object(stack.Stack, 'find')
def test_export_stack_with_identity(self, mock_find):
stack_id = '1234'
stack_name = 'test_stack'
stk = stack.Stack(id=stack_id, name=stack_name)
mock_find.return_value = stk
self._verify(
'openstack.orchestration.v1.stack.Stack.export',
self.proxy.export_stack,
method_args=['IDENTITY'],
expected_args=[self.proxy],
)
mock_find.assert_called_once_with(
mock.ANY, 'IDENTITY', ignore_missing=False
)
def test_export_stack_with_object(self):
stack_id = '1234'
stack_name = 'test_stack'
stk = stack.Stack(id=stack_id, name=stack_name)
self._verify(
'openstack.orchestration.v1.stack.Stack.export',
self.proxy.export_stack,
method_args=[stk],
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)

View File

@ -272,6 +272,23 @@ class TestStack(base.TestCase):
'stacks/%s/%s/abandon' % (FAKE_NAME, FAKE_ID), 'stacks/%s/%s/abandon' % (FAKE_NAME, FAKE_ID),
) )
def test_export(self):
sess = mock.Mock()
sess.default_microversion = None
mock_response = mock.Mock()
mock_response.status_code = 200
mock_response.headers = {}
mock_response.json.return_value = {}
sess.get = mock.Mock(return_value=mock_response)
sot = stack.Stack(**FAKE)
sot.export(sess)
sess.get.assert_called_with(
'stacks/%s/%s/export' % (FAKE_NAME, FAKE_ID),
)
def test_update(self): def test_update(self):
sess = mock.Mock() sess = mock.Mock()
sess.default_microversion = None sess.default_microversion = None

View File

@ -0,0 +1,4 @@
---
features:
- |
Add ``export_stack`` to print stack infomation in a json format