Don't validate rsrc properties with external_id
This also moves the external_id validation from resource create to stack validate. Change-Id: I815599ea3eb8d62a81a78f5e2e2dfc8c9f6dec05 Closes-Bug: #1651681
This commit is contained in:
parent
07b156525b
commit
eb7b5a3d49
|
@ -298,6 +298,10 @@ class Resource(object):
|
|||
self.current_template_id = resource.current_template_id
|
||||
self.root_stack_id = resource.root_stack_id
|
||||
|
||||
@property
|
||||
def external_id(self):
|
||||
return self.t.external_id()
|
||||
|
||||
@property
|
||||
def stack(self):
|
||||
stack = self._stackref()
|
||||
|
@ -864,18 +868,17 @@ class Resource(object):
|
|||
|
||||
runner(timeout=timeout, progress_callback=progress_callback)
|
||||
|
||||
def _validate_external_resource(self, external_id):
|
||||
if self.entity:
|
||||
def validate_external(self):
|
||||
if self.external_id is not None and self.entity:
|
||||
try:
|
||||
self.resource_id = external_id
|
||||
self.resource_id = self.external_id
|
||||
self._show_resource()
|
||||
except Exception as ex:
|
||||
LOG.debug("%s", ex)
|
||||
if self.client_plugin().is_not_found(ex):
|
||||
error_message = _("Invalid external resource: Resource "
|
||||
"%(external_id)s not found in "
|
||||
"%(entity)s.") % {
|
||||
'external_id': external_id,
|
||||
'external_id': self.external_id,
|
||||
'entity': self.entity}
|
||||
raise exception.StackValidationFailed(
|
||||
message="%s" % error_message)
|
||||
|
@ -888,21 +891,19 @@ class Resource(object):
|
|||
Subclasses should provide a handle_create() method to customise
|
||||
creation.
|
||||
"""
|
||||
external = self.t.external_id()
|
||||
if external is not None:
|
||||
self._validate_external_resource(external_id=external)
|
||||
|
||||
yield self._do_action(self.ADOPT,
|
||||
resource_data={'resource_id': external})
|
||||
self.check()
|
||||
return
|
||||
|
||||
action = self.CREATE
|
||||
if (self.action, self.status) != (self.INIT, self.COMPLETE):
|
||||
exc = exception.Error(_('State %s invalid for create')
|
||||
% six.text_type(self.state))
|
||||
raise exception.ResourceFailure(exc, self, action)
|
||||
|
||||
if self.external_id is not None:
|
||||
yield self._do_action(self.ADOPT,
|
||||
resource_data={
|
||||
'resource_id': self.external_id})
|
||||
self.check()
|
||||
return
|
||||
|
||||
# This method can be called when we replace a resource, too. In that
|
||||
# case, a hook has already been dealt with in `Resource.update` so we
|
||||
# shouldn't do it here again:
|
||||
|
@ -1267,14 +1268,14 @@ class Resource(object):
|
|||
if before is None:
|
||||
before = self.frozen_definition()
|
||||
|
||||
external = after.external_id()
|
||||
if before.external_id() != external:
|
||||
after_external_id = after.external_id()
|
||||
if self.external_id != after_external_id:
|
||||
msg = _("Update to property %(prop)s of %(name)s (%(res)s)"
|
||||
) % {'prop': hot_tmpl.HOTemplate20161014.RES_EXTERNAL_ID,
|
||||
'res': self.type(), 'name': self.name}
|
||||
exc = exception.NotSupported(feature=msg)
|
||||
raise exception.ResourceFailure(exc, self, action)
|
||||
elif external is not None:
|
||||
elif after_external_id is not None:
|
||||
LOG.debug("Skip update on external resource.")
|
||||
return
|
||||
|
||||
|
|
|
@ -839,8 +839,11 @@ class Stack(collections.Mapping):
|
|||
# Don't validate identical definitions multiple times
|
||||
if res.name not in unique_defn_names:
|
||||
continue
|
||||
|
||||
try:
|
||||
if res.external_id is not None:
|
||||
res.validate_external()
|
||||
continue
|
||||
|
||||
if self.resource_validate:
|
||||
result = res.validate()
|
||||
else:
|
||||
|
|
|
@ -353,14 +353,12 @@ class ResourceTest(common.HeatTestCase):
|
|||
external_id=external_id)
|
||||
res = generic_rsrc.GenericResource('test_resource', tmpl, self.stack)
|
||||
res.entity = 'test'
|
||||
res.client = mock.Mock()
|
||||
res.client_plugin = mock.Mock()
|
||||
test_obj = mock.Mock()
|
||||
res.client().test = test_obj
|
||||
test_obj.get.side_effect = exception.EntityNotFound
|
||||
|
||||
self.patchobject(res.client_plugin, 'is_not_found',
|
||||
return_value=True)
|
||||
self.patchobject(res, '_show_resource', side_effect=Exception())
|
||||
e = self.assertRaises(exception.StackValidationFailed,
|
||||
scheduler.TaskRunner(res.create))
|
||||
res.validate_external)
|
||||
message = ("Invalid external resource: Resource %(external_id)s not "
|
||||
"found in %(entity)s.") % {'external_id': external_id,
|
||||
'entity': res.entity}
|
||||
|
|
|
@ -2716,6 +2716,7 @@ class StackTest(common.HeatTestCase):
|
|||
new_callable=mock.PropertyMock) as mock_dependencies:
|
||||
mock_dependency = mock.MagicMock()
|
||||
mock_dependency.name = 'res'
|
||||
mock_dependency.external_id = None
|
||||
mock_dependency.validate.side_effect = AssertionError(expected_msg)
|
||||
mock_dependencies.Dependencies.return_value = [mock_dependency]
|
||||
stc = stack.Stack(self.ctx, utils.random_name(), self.tmpl)
|
||||
|
|
Loading…
Reference in New Issue