Merge "Load template files only from their known source" into stable/kilo
This commit is contained in:
commit
f32bddcd12
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
@ -639,10 +643,6 @@ class ProviderTemplateTest(common.HeatTestCase):
|
|||
test_templ = test_templ_file.read()
|
||||
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)
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue