Improve error reporting for missing nested template
When the template for a TemplateResource was missing from the files dict and not otherwise available, we provided misleading feedback when validating the parent template. First, we log that we are fetching the template from a URL, even though we would not actually attempt to do so if it is a file:/// URL. Move the log to after the allowed scheme check, and log debug to indicate when we cannot find a template file. While an exception would be generated in TemplateResource._generate_schema() at resource initialisation time, it is suppressed and saved for later. An empty template is used to generate the properties schema. The exception is re-raised when validate() is called, but during a template validation we only call validate_template(), not validate(), so the first error we run into will be a mismatch of property names. (If no property values were passed in the parent template, we may not even get an error even though we won't be able to create a stack from the given data.) Also re-raise the stored exception at the beginning of validate_template() so that users will see the true source of the error. Change-Id: I1bc100684e1b84fc9ac54ef523d798b317e4dc51 Story: #1739447 Task: 22219
This commit is contained in:
parent
a53219b522
commit
3a96fd7e25
@ -39,13 +39,13 @@ def get(url, allowed_schemes=('http', 'https')):
|
||||
the allowed_schemes argument.
|
||||
Raise an IOError if getting the data fails.
|
||||
"""
|
||||
LOG.info('Fetching data from %s', url)
|
||||
|
||||
components = urllib.parse.urlparse(url)
|
||||
|
||||
if components.scheme not in allowed_schemes:
|
||||
raise URLFetchError(_('Invalid URL scheme %s') % components.scheme)
|
||||
|
||||
LOG.info('Fetching data from %s', url)
|
||||
|
||||
if components.scheme == 'file':
|
||||
try:
|
||||
return urllib.request.urlopen(url).read()
|
||||
|
@ -195,6 +195,10 @@ class TemplateResource(stack_resource.StackResource):
|
||||
reported_excp = None
|
||||
t_data = self.stack.t.files.get(self.template_url)
|
||||
stored_t_data = t_data
|
||||
|
||||
if t_data is None:
|
||||
LOG.debug('TemplateResource data file "%s" not found in files.',
|
||||
self.template_url)
|
||||
if not t_data and self.template_url.endswith((".yaml", ".template")):
|
||||
try:
|
||||
t_data = self.get_template_file(self.template_url,
|
||||
@ -257,9 +261,8 @@ class TemplateResource(stack_resource.StackResource):
|
||||
raise exception.StackValidationFailed(message=msg)
|
||||
|
||||
def validate(self):
|
||||
if self.validation_exception is not None:
|
||||
msg = six.text_type(self.validation_exception)
|
||||
raise exception.StackValidationFailed(message=msg)
|
||||
# Calls validate_template()
|
||||
result = super(TemplateResource, self).validate()
|
||||
|
||||
try:
|
||||
self.template_data()
|
||||
@ -280,7 +283,14 @@ class TemplateResource(stack_resource.StackResource):
|
||||
facade_cls = fri.get_class(files=self.stack.t.files)
|
||||
self._validate_against_facade(facade_cls)
|
||||
|
||||
return super(TemplateResource, self).validate()
|
||||
return result
|
||||
|
||||
def validate_template(self):
|
||||
if self.validation_exception is not None:
|
||||
msg = six.text_type(self.validation_exception)
|
||||
raise exception.StackValidationFailed(message=msg)
|
||||
|
||||
return super(TemplateResource, self).validate_template()
|
||||
|
||||
def handle_adopt(self, resource_data=None):
|
||||
return self.create_with_template(self.child_template(),
|
||||
|
@ -792,9 +792,11 @@ outputs:
|
||||
value:
|
||||
not-important
|
||||
'''
|
||||
template = yaml.safe_load(self.template)
|
||||
del template['resources']['thisone']['properties']['two']
|
||||
try:
|
||||
self.stack_create(
|
||||
template=self.template,
|
||||
template=yaml.safe_dump(template),
|
||||
environment=self.env,
|
||||
files={'facade.yaml': self.templ_facade,
|
||||
'concrete.yaml': templ_missing_parameter},
|
||||
|
Loading…
Reference in New Issue
Block a user