Merge "Avoid passing templates/files over RPC"

This commit is contained in:
Jenkins 2016-05-16 23:37:17 +00:00 committed by Gerrit Code Review
commit ec05fc909d
2 changed files with 165 additions and 28 deletions

View File

@ -31,6 +31,7 @@ from heat.engine import resource
from heat.engine import scheduler
from heat.engine import stack as parser
from heat.engine import template
from heat.objects import raw_template
from heat.objects import stack as stack_object
from heat.objects import stack_lock
from heat.rpc import api as rpc_api
@ -266,7 +267,7 @@ class StackResource(resource.Resource):
timeout_mins = self.stack.timeout_mins
stack_user_project_id = self.stack.stack_user_project_id
kwargs = self._stack_kwargs(user_params, child_template)
kwargs = self._stack_kwargs(user_params, child_template, adopt_data)
adopt_data_str = None
if adopt_data is not None:
@ -293,11 +294,18 @@ class StackResource(resource.Resource):
'parent_resource_name': self.name
})
with self.translate_remote_exceptions:
result = self.rpc_client()._create_stack(self.context, **kwargs)
result = None
try:
result = self.rpc_client()._create_stack(self.context,
**kwargs)
finally:
if adopt_data is None and not result:
raw_template.RawTemplate.delete(self.context,
kwargs['template_id'])
self.resource_id_set(result['stack_id'])
def _stack_kwargs(self, user_params, child_template):
def _stack_kwargs(self, user_params, child_template, adopt_data=None):
if user_params is None:
user_params = self.child_params()
@ -311,11 +319,20 @@ class StackResource(resource.Resource):
parsed_template = self._child_parsed_template(child_template,
child_env)
return {
'template': parsed_template.t,
'params': child_env.user_env_as_dict(),
'files': parsed_template.files
}
if adopt_data is None:
template_id = parsed_template.store(self.context)
return {
'template_id': template_id,
'template': None,
'params': None,
'files': None,
}
else:
return {
'template': parsed_template.t,
'params': child_env.user_env_as_dict(),
'files': parsed_template.files,
}
def raise_local_exception(self, ex):
warnings.warn('raise_local_exception() is deprecated. Use the '
@ -439,7 +456,14 @@ class StackResource(resource.Resource):
'args': {rpc_api.PARAM_TIMEOUT: timeout_mins}
})
with self.translate_remote_exceptions:
self.rpc_client().update_stack(self.context, **kwargs)
result = None
try:
result = self.rpc_client()._update_stack(self.context,
**kwargs)
finally:
if not result:
raw_template.RawTemplate.delete(self.context,
kwargs['template_id'])
return cookie
def check_update_complete(self, cookie=None):

View File

@ -25,6 +25,7 @@ from heat.common import template_format
from heat.engine.resources import stack_resource
from heat.engine import stack as parser
from heat.engine import template as templatem
from heat.objects import raw_template
from heat.objects import stack as stack_object
from heat.objects import stack_lock
from heat.tests import common
@ -826,6 +827,16 @@ class WithTemplateTest(StackResourceBaseTest):
adopt_data={'template': 'foo', 'environment': 'eee'})),
]
class IntegerMatch(object):
def __eq__(self, other):
if getattr(self, 'match', None) is not None:
return other == self.match
if not isinstance(other, six.integer_types):
return False
self.match = other
return True
def test_create_with_template(self):
child_env = {'parameter_defaults': {},
'event_sinks': [],
@ -841,15 +852,24 @@ class WithTemplateTest(StackResourceBaseTest):
self.parent_resource.create_with_template(
self.empty_temp, user_params=self.params,
timeout_mins=self.timeout_mins, adopt_data=self.adopt_data)
adopt_data_str = None
if self.adopt_data:
if self.adopt_data is not None:
adopt_data_str = json.dumps(self.adopt_data)
tmpl_args = {
'template': self.empty_temp.t,
'params': child_env,
'files': {},
}
else:
adopt_data_str = None
tmpl_args = {
'template_id': self.IntegerMatch(),
'template': None,
'params': None,
'files': None,
}
rpcc.return_value._create_stack.assert_called_once_with(
self.ctx,
stack_name=res_name,
template=self.empty_temp.t,
params=child_env,
files={},
args={'disable_rollback': True,
'adopt_stack_data': adopt_data_str,
'timeout_mins': self.timeout_mins},
@ -858,16 +878,12 @@ class WithTemplateTest(StackResourceBaseTest):
parent_resource_name='test',
user_creds_id='uc123',
owner_id=self.parent_stack.id,
nested_depth=1)
nested_depth=1,
**tmpl_args)
def test_update_with_template(self):
nested = mock.MagicMock()
nested.updated_time = 'now_time'
nested.state = ('CREATE', 'COMPLETE')
nested.identifier.return_value = {'stack_identifier':
'stack-identifier'}
self.parent_resource.nested = mock.MagicMock(return_value=nested)
self.parent_resource._nested = nested
def test_create_with_template_failure(self):
class StackValidationFailed_Remote(exception.StackValidationFailed):
pass
child_env = {'parameter_defaults': {},
'event_sinks': [],
@ -876,20 +892,117 @@ class WithTemplateTest(StackResourceBaseTest):
'encrypted_param_names': []}
self.parent_resource.child_params = mock.Mock(
return_value=self.params)
res_name = self.parent_resource.physical_resource_name()
rpcc = mock.Mock()
self.parent_resource.rpc_client = rpcc
rpcc.return_value._create_stack.return_value = {'stack_id': 'pancakes'}
remote_exc = StackValidationFailed_Remote(message='oops')
rpcc.return_value._create_stack.side_effect = remote_exc
self.assertRaises(exception.ResourceFailure,
self.parent_resource.create_with_template,
self.empty_temp, user_params=self.params,
timeout_mins=self.timeout_mins,
adopt_data=self.adopt_data)
if self.adopt_data is not None:
adopt_data_str = json.dumps(self.adopt_data)
tmpl_args = {
'template': self.empty_temp.t,
'params': child_env,
'files': {},
}
else:
adopt_data_str = None
tmpl_args = {
'template_id': self.IntegerMatch(),
'template': None,
'params': None,
'files': None,
}
rpcc.return_value._create_stack.assert_called_once_with(
self.ctx,
stack_name=res_name,
args={'disable_rollback': True,
'adopt_stack_data': adopt_data_str,
'timeout_mins': self.timeout_mins},
environment_files=None,
stack_user_project_id='aprojectid',
parent_resource_name='test',
user_creds_id='uc123',
owner_id=self.parent_stack.id,
nested_depth=1,
**tmpl_args)
if self.adopt_data is None:
stored_tmpl_id = tmpl_args['template_id'].match
self.assertIsNotNone(stored_tmpl_id)
self.assertRaises(exception.NotFound,
raw_template.RawTemplate.get_by_id,
self.ctx, stored_tmpl_id)
def test_update_with_template(self):
if self.adopt_data is not None:
return
nested = mock.MagicMock()
nested.updated_time = 'now_time'
nested.state = ('CREATE', 'COMPLETE')
nested.identifier.return_value = {'stack_identifier':
'stack-identifier'}
self.parent_resource.nested = mock.MagicMock(return_value=nested)
self.parent_resource._nested = nested
self.parent_resource.child_params = mock.Mock(
return_value=self.params)
rpcc = mock.Mock()
self.parent_resource.rpc_client = rpcc
rpcc.return_value._update_stack.return_value = {'stack_id': 'pancakes'}
self.parent_resource.update_with_template(
self.empty_temp, user_params=self.params,
timeout_mins=self.timeout_mins)
rpcc.return_value.update_stack.assert_called_once_with(
rpcc.return_value._update_stack.assert_called_once_with(
self.ctx,
stack_identity={'stack_identifier': 'stack-identifier'},
template=self.empty_temp.t,
params=child_env,
files={},
template_id=self.IntegerMatch(),
template=None,
params=None,
files=None,
args={'timeout_mins': self.timeout_mins})
def test_update_with_template_failure(self):
class StackValidationFailed_Remote(exception.StackValidationFailed):
pass
if self.adopt_data is not None:
return
nested = mock.MagicMock()
nested.updated_time = 'now_time'
nested.state = ('CREATE', 'COMPLETE')
nested.identifier.return_value = {'stack_identifier':
'stack-identifier'}
self.parent_resource.nested = mock.MagicMock(return_value=nested)
self.parent_resource._nested = nested
self.parent_resource.child_params = mock.Mock(
return_value=self.params)
rpcc = mock.Mock()
self.parent_resource.rpc_client = rpcc
remote_exc = StackValidationFailed_Remote(message='oops')
rpcc.return_value._update_stack.side_effect = remote_exc
self.assertRaises(exception.ResourceFailure,
self.parent_resource.update_with_template,
self.empty_temp, user_params=self.params,
timeout_mins=self.timeout_mins)
template_id = self.IntegerMatch()
rpcc.return_value._update_stack.assert_called_once_with(
self.ctx,
stack_identity={'stack_identifier': 'stack-identifier'},
template_id=template_id,
template=None,
params=None,
files=None,
args={'timeout_mins': self.timeout_mins})
self.assertIsNotNone(template_id.match)
self.assertRaises(exception.NotFound,
raw_template.RawTemplate.get_by_id,
self.ctx, template_id.match)
class RaiseLocalException(StackResourceBaseTest):