Add owner_id to new _create_stack RPC interface
Adds a new "internal" _create_stack RPC call, which exposes a superset of the existing RPC interfaces, intended only for engine-to-engine usage, not for exposure via the user-facing API's (hence the prefix) This patch exposes "owner_id" via the new call, which enables creation of nested stacks via an RPC call, instead of creating the stack directly. Change-Id: I355c608e657cb9dae2d2b38658b0b247040de6b9 blueprint: decouple-nested
This commit is contained in:
parent
3dee21c30d
commit
f899548500
|
@ -152,10 +152,22 @@ class EngineClient(object):
|
|||
:param files: files referenced from the environment.
|
||||
:param args: Request parameters/args passed from API
|
||||
"""
|
||||
return self._create_stack(ctxt, stack_name, template, params, files,
|
||||
args)
|
||||
|
||||
def _create_stack(self, ctxt, stack_name, template, params, files, args,
|
||||
owner_id=None):
|
||||
"""
|
||||
Internal create_stack interface for engine-to-engine communication via
|
||||
RPC. Allows some additional options which should not be exposed to
|
||||
users via the API:
|
||||
:param owner_id: parent stack ID for nested stacks
|
||||
"""
|
||||
return self.call(ctxt,
|
||||
self.make_msg('create_stack', stack_name=stack_name,
|
||||
template=template,
|
||||
params=params, files=files, args=args))
|
||||
params=params, files=files, args=args,
|
||||
owner_id=owner_id))
|
||||
|
||||
def update_stack(self, ctxt, stack_identity, template, params,
|
||||
files, args):
|
||||
|
|
|
@ -511,7 +511,8 @@ class CfnStackControllerTest(HeatTestCase):
|
|||
'template': self.template,
|
||||
'params': engine_parms,
|
||||
'files': {},
|
||||
'args': engine_args})
|
||||
'args': engine_args,
|
||||
'owner_id': None})
|
||||
).AndReturn(engine_resp)
|
||||
|
||||
self.m.ReplayAll()
|
||||
|
@ -557,7 +558,8 @@ class CfnStackControllerTest(HeatTestCase):
|
|||
'template': self.template,
|
||||
'params': engine_parms,
|
||||
'files': {},
|
||||
'args': engine_args})
|
||||
'args': engine_args,
|
||||
'owner_id': None})
|
||||
).AndReturn(engine_resp)
|
||||
|
||||
self.m.ReplayAll()
|
||||
|
@ -603,7 +605,8 @@ class CfnStackControllerTest(HeatTestCase):
|
|||
'template': self.template,
|
||||
'params': engine_parms,
|
||||
'files': {},
|
||||
'args': engine_args})
|
||||
'args': engine_args,
|
||||
'owner_id': None})
|
||||
).AndReturn(engine_resp)
|
||||
|
||||
self.m.ReplayAll()
|
||||
|
@ -649,7 +652,8 @@ class CfnStackControllerTest(HeatTestCase):
|
|||
'template': self.template,
|
||||
'params': engine_parms,
|
||||
'files': {},
|
||||
'args': engine_args})
|
||||
'args': engine_args,
|
||||
'owner_id': None})
|
||||
).AndReturn(engine_resp)
|
||||
|
||||
self.m.ReplayAll()
|
||||
|
@ -695,7 +699,8 @@ class CfnStackControllerTest(HeatTestCase):
|
|||
'template': self.template,
|
||||
'params': engine_parms,
|
||||
'files': {},
|
||||
'args': engine_args})
|
||||
'args': engine_args,
|
||||
'owner_id': None})
|
||||
).AndReturn(engine_resp)
|
||||
|
||||
self.m.ReplayAll()
|
||||
|
@ -779,7 +784,8 @@ class CfnStackControllerTest(HeatTestCase):
|
|||
'template': self.template,
|
||||
'params': engine_parms,
|
||||
'files': {},
|
||||
'args': engine_args})
|
||||
'args': engine_args,
|
||||
'owner_id': None})
|
||||
).AndRaise(AttributeError())
|
||||
|
||||
policy.Enforcer.enforce(dummy_req.context, 'CreateStack'
|
||||
|
@ -791,7 +797,8 @@ class CfnStackControllerTest(HeatTestCase):
|
|||
'template': self.template,
|
||||
'params': engine_parms,
|
||||
'files': {},
|
||||
'args': engine_args})
|
||||
'args': engine_args,
|
||||
'owner_id': None})
|
||||
).AndRaise(heat_exception.UnknownUserParameter(key='test'))
|
||||
|
||||
policy.Enforcer.enforce(dummy_req.context, 'CreateStack'
|
||||
|
@ -803,7 +810,8 @@ class CfnStackControllerTest(HeatTestCase):
|
|||
'template': self.template,
|
||||
'params': engine_parms,
|
||||
'files': {},
|
||||
'args': engine_args})
|
||||
'args': engine_args,
|
||||
'owner_id': None})
|
||||
).AndRaise(heat_exception.UserParameterMissing(key='test'))
|
||||
|
||||
self.m.ReplayAll()
|
||||
|
@ -842,7 +850,8 @@ class CfnStackControllerTest(HeatTestCase):
|
|||
'template': self.template,
|
||||
'params': engine_parms,
|
||||
'files': {},
|
||||
'args': engine_args})
|
||||
'args': engine_args,
|
||||
'owner_id': None})
|
||||
).AndRaise(heat_exception.StackExists(stack_name='test'))
|
||||
|
||||
self.m.ReplayAll()
|
||||
|
@ -875,7 +884,8 @@ class CfnStackControllerTest(HeatTestCase):
|
|||
'template': self.template,
|
||||
'params': engine_parms,
|
||||
'files': {},
|
||||
'args': engine_args})
|
||||
'args': engine_args,
|
||||
'owner_id': None})
|
||||
).AndRaise(heat_exception.StackValidationFailed(
|
||||
message='Something went wrong'))
|
||||
|
||||
|
|
|
@ -676,7 +676,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'params': {'parameters': parameters,
|
||||
'resource_registry': {}},
|
||||
'files': {},
|
||||
'args': {'timeout_mins': 30}})
|
||||
'args': {'timeout_mins': 30},
|
||||
'owner_id': None})
|
||||
).AndReturn(dict(identity))
|
||||
self.m.ReplayAll()
|
||||
|
||||
|
@ -713,7 +714,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'params': {'parameters': parameters,
|
||||
'resource_registry': {}},
|
||||
'files': {'my.yaml': 'This is the file contents.'},
|
||||
'args': {'timeout_mins': 30}})
|
||||
'args': {'timeout_mins': 30},
|
||||
'owner_id': None})
|
||||
).AndReturn(dict(identity))
|
||||
self.m.ReplayAll()
|
||||
|
||||
|
@ -750,7 +752,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'params': {'parameters': parameters,
|
||||
'resource_registry': {}},
|
||||
'files': {},
|
||||
'args': {'timeout_mins': 30}})
|
||||
'args': {'timeout_mins': 30},
|
||||
'owner_id': None})
|
||||
).AndRaise(to_remote_error(AttributeError()))
|
||||
rpc_client.EngineClient.call(
|
||||
req.context,
|
||||
|
@ -760,7 +763,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'params': {'parameters': parameters,
|
||||
'resource_registry': {}},
|
||||
'files': {},
|
||||
'args': {'timeout_mins': 30}})
|
||||
'args': {'timeout_mins': 30},
|
||||
'owner_id': None})
|
||||
).AndRaise(to_remote_error(unknown_parameter))
|
||||
rpc_client.EngineClient.call(
|
||||
req.context,
|
||||
|
@ -770,7 +774,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'params': {'parameters': parameters,
|
||||
'resource_registry': {}},
|
||||
'files': {},
|
||||
'args': {'timeout_mins': 30}})
|
||||
'args': {'timeout_mins': 30},
|
||||
'owner_id': None})
|
||||
).AndRaise(to_remote_error(missing_parameter))
|
||||
self.m.ReplayAll()
|
||||
resp = request_with_middleware(fault.FaultWrapper,
|
||||
|
@ -817,7 +822,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'params': {'parameters': parameters,
|
||||
'resource_registry': {}},
|
||||
'files': {},
|
||||
'args': {'timeout_mins': 30}})
|
||||
'args': {'timeout_mins': 30},
|
||||
'owner_id': None})
|
||||
).AndRaise(to_remote_error(error))
|
||||
self.m.ReplayAll()
|
||||
|
||||
|
@ -870,7 +876,8 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
'params': {'parameters': parameters,
|
||||
'resource_registry': {}},
|
||||
'files': {},
|
||||
'args': {'timeout_mins': 30}})
|
||||
'args': {'timeout_mins': 30},
|
||||
'owner_id': None})
|
||||
).AndRaise(to_remote_error(error))
|
||||
self.m.ReplayAll()
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ Unit Tests for heat.rpc.client
|
|||
"""
|
||||
|
||||
|
||||
import copy
|
||||
import mock
|
||||
import stubout
|
||||
import testtools
|
||||
|
@ -47,7 +48,12 @@ class EngineRpcAPITestCase(testtools.TestCase):
|
|||
expected_retval = 'foo' if method == 'call' else None
|
||||
|
||||
kwargs.pop('version', None)
|
||||
expected_msg = self.rpcapi.make_msg(method, **kwargs)
|
||||
|
||||
if 'expected_message' in kwargs:
|
||||
expected_message = kwargs['expected_message']
|
||||
del kwargs['expected_message']
|
||||
else:
|
||||
expected_message = self.rpcapi.make_msg(method, **kwargs)
|
||||
|
||||
cast_and_call = ['delete_stack']
|
||||
if rpc_method == 'call' and method in cast_and_call:
|
||||
|
@ -59,7 +65,7 @@ class EngineRpcAPITestCase(testtools.TestCase):
|
|||
retval = getattr(self.rpcapi, method)(ctxt, **kwargs)
|
||||
|
||||
self.assertEqual(expected_retval, retval)
|
||||
expected_args = [ctxt, expected_msg, mock.ANY]
|
||||
expected_args = [ctxt, expected_message, mock.ANY]
|
||||
actual_args, _ = mock_rpc_method.call_args
|
||||
for expected_arg, actual_arg in zip(expected_args,
|
||||
actual_args):
|
||||
|
@ -103,11 +109,16 @@ class EngineRpcAPITestCase(testtools.TestCase):
|
|||
args={'timeout_mins': u'30'})
|
||||
|
||||
def test_create_stack(self):
|
||||
self._test_engine_api('create_stack', 'call', stack_name='wordpress',
|
||||
template={u'Foo': u'bar'},
|
||||
params={u'InstanceType': u'm1.xlarge'},
|
||||
files={u'a_file': u'the contents'},
|
||||
args={'timeout_mins': u'30'})
|
||||
kwargs = dict(stack_name='wordpress',
|
||||
template={u'Foo': u'bar'},
|
||||
params={u'InstanceType': u'm1.xlarge'},
|
||||
files={u'a_file': u'the contents'},
|
||||
args={'timeout_mins': u'30'})
|
||||
call_kwargs = copy.deepcopy(kwargs)
|
||||
call_kwargs['owner_id'] = None
|
||||
expected_message = self.rpcapi.make_msg('create_stack', **call_kwargs)
|
||||
kwargs['expected_message'] = expected_message
|
||||
self._test_engine_api('create_stack', 'call', **kwargs)
|
||||
|
||||
def test_update_stack(self):
|
||||
self._test_engine_api('update_stack', 'call',
|
||||
|
|
Loading…
Reference in New Issue