diff options
author | Jenkins <jenkins@review.openstack.org> | 2016-01-19 20:27:38 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2016-01-19 20:27:39 +0000 |
commit | f32bddcd12cd0c9e56f1daeb4519f610f729d2f7 (patch) | |
tree | 21c5743dafe2aabbfaffb76a30f35eaa0753912b | |
parent | ec446e1fb56bb073b71197fa9f5594d885ae27b4 (diff) | |
parent | fa19a617a79fd1cb0d892bb8ea87c4b9f6398c34 (diff) | |
download | heat-f32bddcd12cd0c9e56f1daeb4519f610f729d2f7.tar.gz |
Merge "Load template files only from their known source" into stable/kilo2015.1.3
-rw-r--r-- | heat/engine/environment.py | 35 | ||||
-rw-r--r-- | heat/engine/resource.py | 11 | ||||
-rw-r--r-- | heat/engine/resources/openstack/heat/resource_group.py | 6 | ||||
-rw-r--r-- | heat/engine/resources/template_resource.py | 11 | ||||
-rw-r--r-- | heat/engine/service.py | 4 | ||||
-rw-r--r-- | heat/tests/test_provider_template.py | 10 | ||||
-rw-r--r-- | heat/tests/test_resource.py | 5 |
7 files changed, 51 insertions, 31 deletions
diff --git a/heat/engine/environment.py b/heat/engine/environment.py index bd81c8677..41d91d5af 100644 --- a/heat/engine/environment.py +++ b/heat/engine/environment.py @@ -112,6 +112,12 @@ class ResourceInfo(object): def matches(self, resource_type): return False + def get_class(self): + raise NotImplemented + + def get_class_to_instantiate(self): + return self.get_class() + def __str__(self): return '[%s](User:%s) %s -> %s' % (self.description, self.user_resource, @@ -140,10 +146,20 @@ class TemplateResourceInfo(ResourceInfo): def get_class(self): from heat.engine.resources import template_resource + if self.user_resource: + allowed_schemes = template_resource.REMOTE_SCHEMES + else: + allowed_schemes = template_resource.LOCAL_SCHEMES + data = template_resource.TemplateResource.get_template_file( + self.template_name, + allowed_schemes) env = self.registry.environment - return template_resource.generate_class(str(self.name), - self.template_name, - env) + return template_resource.generate_class_from_template(str(self.name), + data, env) + + def get_class_to_instantiate(self): + from heat.engine.resources import template_resource + return template_resource.TemplateResource class MapResourceInfo(ResourceInfo): @@ -398,6 +414,13 @@ class ResourceRegistry(object): return match def get_class(self, resource_type, resource_name=None): + info = self.get_resource_info(resource_type, + resource_name=resource_name) + if info is None: + raise exception.ResourceTypeNotFound(type_name=resource_type) + return info.get_class() + + def get_class_to_instantiate(self, resource_type, resource_name=None): if resource_type == "": msg = _('Resource "%s" has no type') % resource_name raise exception.StackValidationFailed(message=msg) @@ -414,7 +437,7 @@ class ResourceRegistry(object): if info is None: msg = _("Unknown resource Type : %s") % resource_type raise exception.StackValidationFailed(message=msg) - return info.get_class() + return info.get_class_to_instantiate() def as_dict(self): """Return user resources in a dict format.""" @@ -521,6 +544,10 @@ class Environment(object): def get_class(self, resource_type, resource_name=None): return self.registry.get_class(resource_type, resource_name) + def get_class_to_instantiate(self, resource_type, resource_name=None): + return self.registry.get_class_to_instantiate(resource_type, + resource_name) + def get_types(self, support_status=None): return self.registry.get_types(support_status) diff --git a/heat/engine/resource.py b/heat/engine/resource.py index d934a1e0e..0c01504de 100644 --- a/heat/engine/resource.py +++ b/heat/engine/resource.py @@ -137,14 +137,11 @@ class Resource(object): # Call is already for a subclass, so pass it through ResourceClass = cls else: - from heat.engine.resources import template_resource - registry = stack.env.registry - try: - ResourceClass = registry.get_class(definition.resource_type, - resource_name=name) - except exception.NotFound: - ResourceClass = template_resource.TemplateResource + ResourceClass = registry.get_class_to_instantiate( + definition.resource_type, + resource_name=name) + assert issubclass(ResourceClass, Resource) return super(Resource, cls).__new__(ResourceClass) diff --git a/heat/engine/resources/openstack/heat/resource_group.py b/heat/engine/resources/openstack/heat/resource_group.py index ddb6dd91f..a98b00405 100644 --- a/heat/engine/resources/openstack/heat/resource_group.py +++ b/heat/engine/resources/openstack/heat/resource_group.py @@ -193,11 +193,7 @@ class ResourceGroup(stack_resource.StackResource): val_templ = template.Template(test_tmpl) res_def = val_templ.resource_definitions(self.stack)["0"] # make sure we can resolve the nested resource type - try: - self.stack.env.get_class(res_def.resource_type) - except exception.NotFound: - # its a template resource - pass + self.stack.env.get_class_to_instantiate(res_def.resource_type) try: name = "%s-%s" % (self.stack.name, self.name) diff --git a/heat/engine/resources/template_resource.py b/heat/engine/resources/template_resource.py index ffc74601b..e8c15a5c9 100644 --- a/heat/engine/resources/template_resource.py +++ b/heat/engine/resources/template_resource.py @@ -26,8 +26,11 @@ from heat.engine.resources import stack_resource from heat.engine import template -def generate_class(name, template_name, env): - data = TemplateResource.get_template_file(template_name, ('file',)) +REMOTE_SCHEMES = ('http', 'https') +LOCAL_SCHEMES = ('file',) + + +def generate_class_from_template(name, data, env): tmpl = template.Template(template_format.parse(data)) props, attrs = TemplateResource.get_schemas(tmpl, env.param_defaults) cls = type(name, (TemplateResource,), @@ -79,9 +82,9 @@ class TemplateResource(stack_resource.StackResource): self.template_name = tri.template_name self.resource_type = tri.name if tri.user_resource: - self.allowed_schemes = ('http', 'https') + self.allowed_schemes = REMOTE_SCHEMES else: - self.allowed_schemes = ('http', 'https', 'file') + self.allowed_schemes = REMOTE_SCHEMES + LOCAL_SCHEMES return tri diff --git a/heat/engine/service.py b/heat/engine/service.py index 070244e07..8fe8746db 100644 --- a/heat/engine/service.py +++ b/heat/engine/service.py @@ -989,8 +989,6 @@ class EngineService(service.Service): """ try: resource_class = resources.global_env().get_class(type_name) - except exception.StackValidationFailed: - raise exception.ResourceTypeNotFound(type_name=type_name) except exception.NotFound as ex: raise exception.StackValidationFailed(message=ex.message) @@ -1021,8 +1019,6 @@ class EngineService(service.Service): try: return resources.global_env().get_class( type_name).resource_to_template(type_name) - except exception.StackValidationFailed: - raise exception.ResourceTypeNotFound(type_name=type_name) except exception.NotFound as ex: raise exception.StackValidationFailed(message=ex.message) diff --git a/heat/tests/test_provider_template.py b/heat/tests/test_provider_template.py index 068468dcc..01b6bc675 100644 --- a/heat/tests/test_provider_template.py +++ b/heat/tests/test_provider_template.py @@ -613,7 +613,11 @@ class ProviderTemplateTest(common.HeatTestCase): env_str = {'resource_registry': {'resources': {'fred': { "OS::ResourceType": test_templ_name}}}} - env = environment.Environment(env_str) + global_env = environment.Environment({}, user_env=False) + global_env.load(env_str) + with mock.patch('heat.engine.resources._environment', + global_env): + env = environment.Environment({}) cls = env.get_class('OS::ResourceType', 'fred') self.assertNotEqual(template_resource.TemplateResource, cls) self.assertTrue(issubclass(cls, template_resource.TemplateResource)) @@ -640,10 +644,6 @@ class ProviderTemplateTest(common.HeatTestCase): self.assertTrue(test_templ, "Empty test template") self.m.StubOutWithMock(urlfetch, "get") urlfetch.get(test_templ_name, - allowed_schemes=('file',) - ).AndRaise(urlfetch.URLFetchError( - _('Failed to retrieve template'))) - urlfetch.get(test_templ_name, allowed_schemes=('http', 'https')).AndReturn(test_templ) parsed_test_templ = template_format.parse(test_templ) self.m.ReplayAll() diff --git a/heat/tests/test_resource.py b/heat/tests/test_resource.py index 2dda46eab..ab4052caf 100644 --- a/heat/tests/test_resource.py +++ b/heat/tests/test_resource.py @@ -67,12 +67,13 @@ class ResourceTest(common.HeatTestCase): self.patch('heat.engine.resource.warnings') def test_get_class_ok(self): - cls = resources.global_env().get_class('GenericResourceType') + cls = resources.global_env().get_class_to_instantiate( + 'GenericResourceType') self.assertEqual(generic_rsrc.GenericResource, cls) def test_get_class_noexist(self): self.assertRaises(exception.StackValidationFailed, - resources.global_env().get_class, + resources.global_env().get_class_to_instantiate, 'NoExistResourceType') def test_resource_new_ok(self): |