Merge "Implement stack export in openstacksdk"
This commit is contained in:
commit
e31f54551b
@ -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
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Add ``export_stack`` to print stack infomation in a json format
|
Loading…
Reference in New Issue
Block a user