From b1da94e10c4961210f60e86bd2acc7e007c626dc Mon Sep 17 00:00:00 2001 From: ricolin Date: Wed, 20 Jul 2016 13:18:22 +0800 Subject: [PATCH] Add validate for external resources. Add check for external resource. Make sure we can avoid parsing wrong resource parameter to other resources. blueprint external-resources Change-Id: I95dd46ac25b98765d9fecd566bea2019297aac02 --- heat/engine/resource.py | 19 +++++++++++++++++++ heat/tests/test_resource.py | 20 ++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/heat/engine/resource.py b/heat/engine/resource.py index 313fdc33cc..38fc9c646c 100644 --- a/heat/engine/resource.py +++ b/heat/engine/resource.py @@ -858,6 +858,23 @@ class Resource(object): runner = scheduler.TaskRunner(self.adopt, **adopt_data) runner(timeout=timeout) + def _validate_external_resource(self, external_id): + if self.entity: + try: + self.resource_id = 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, + 'entity': self.entity} + raise exception.StackValidationFailed( + message="%s" % error_message) + raise + @scheduler.wrappertask def create(self): """Create the resource. @@ -867,6 +884,8 @@ class Resource(object): """ 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() diff --git a/heat/tests/test_resource.py b/heat/tests/test_resource.py index 1b013e3f72..81b22e2411 100644 --- a/heat/tests/test_resource.py +++ b/heat/tests/test_resource.py @@ -344,6 +344,26 @@ class ResourceTest(common.HeatTestCase): self.assertEqual((res.CHECK, res.COMPLETE), res.state) self.assertEqual('f00d', res.resource_id) + def test_create_from_external_not_found(self): + external_id = 'f00d' + tmpl = rsrc_defn.ResourceDefinition( + 'test_resource', 'GenericResourceType', + 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 + + e = self.assertRaises(exception.StackValidationFailed, + scheduler.TaskRunner(res.create)) + message = ("Invalid external resource: Resource %(external_id)s not " + "found in %(entity)s.") % {'external_id': external_id, + 'entity': res.entity} + self.assertEqual(message, six.text_type(e)) + def test_updated_from_external(self): tmpl = rsrc_defn.ResourceDefinition('test_resource', 'GenericResourceType')