Add support for using ToscaTemplate with a parsed template string
* This patchset adds the ability for a ToscaTemplate object to be created with a parsed string instead of a file or URL. Change-Id: I8e14d12f184bb4ebb5c22770f9c5017e946fb7ce Closes-Bug: 1525377
This commit is contained in:
parent
1a6249ef62
commit
b17656cb20
@ -31,10 +31,11 @@ class ImportsLoader(object):
|
||||
('file', 'repository', 'namespace_uri',
|
||||
'namespace_prefix')
|
||||
|
||||
def __init__(self, importslist, path, type_definition_list=None):
|
||||
def __init__(self, importslist, path, type_definition_list=None,
|
||||
tpl=None):
|
||||
self.importslist = importslist
|
||||
self.custom_defs = {}
|
||||
if not path:
|
||||
if not path and not tpl:
|
||||
msg = _('Input tosca template is not provided.')
|
||||
log.warning(msg)
|
||||
ExceptionCollector.appendException(ValidationError(message=msg))
|
||||
@ -136,6 +137,8 @@ class ImportsLoader(object):
|
||||
+----------+--------+------------------------------+
|
||||
| file | file | OK |
|
||||
| file | URL | OK |
|
||||
| preparsed| file | file must be a full path |
|
||||
| preparsed| URL | OK |
|
||||
| URL | file | file must be a relative path |
|
||||
| URL | URL | OK |
|
||||
+----------+--------+------------------------------+
|
||||
@ -164,28 +167,42 @@ class ImportsLoader(object):
|
||||
return YAML_LOADER(file_name, False)
|
||||
elif not namespace_uri:
|
||||
import_template = None
|
||||
a_file = True
|
||||
main_a_file = os.path.isfile(self.path)
|
||||
if main_a_file:
|
||||
if os.path.isfile(file_name):
|
||||
if self.path:
|
||||
if toscaparser.utils.urlutils.UrlUtils.validate_url(self.path):
|
||||
if os.path.isabs(file_name):
|
||||
msg = (_('Absolute file name "%(name)s" cannot be '
|
||||
'used in a URL-based input template '
|
||||
'"%(template)s".')
|
||||
% {'name': file_name, 'template': self.path})
|
||||
log.error(msg)
|
||||
ExceptionCollector.appendException(ImportError(msg))
|
||||
return
|
||||
import_template = toscaparser.utils.urlutils.UrlUtils.\
|
||||
join_url(self.path, file_name)
|
||||
a_file = False
|
||||
else:
|
||||
a_file = True
|
||||
main_a_file = os.path.isfile(self.path)
|
||||
if main_a_file:
|
||||
if os.path.isfile(file_name):
|
||||
import_template = file_name
|
||||
else:
|
||||
full_path = os.path.join(
|
||||
os.path.dirname(os.path.abspath(self.path)),
|
||||
file_name)
|
||||
if os.path.isfile(full_path):
|
||||
import_template = full_path
|
||||
else: # template is pre-parsed
|
||||
if os.path.isabs(file_name):
|
||||
import_template = file_name
|
||||
else:
|
||||
full_path = os.path.join(
|
||||
os.path.dirname(os.path.abspath(self.path)),
|
||||
file_name)
|
||||
if os.path.isfile(full_path):
|
||||
import_template = full_path
|
||||
else: # main_a_url
|
||||
if os.path.isabs(file_name):
|
||||
msg = (_('Absolute file name "%(name)s" cannot be used '
|
||||
'in a URL-based input template "%(template)s".')
|
||||
% {'name': file_name, 'template': self.path})
|
||||
msg = (_('Relative file name "%(name)s" cannot be used '
|
||||
'in a pre-parsed input template.')
|
||||
% {'name': file_name})
|
||||
log.error(msg)
|
||||
ExceptionCollector.appendException(ImportError(msg))
|
||||
return
|
||||
import_template = toscaparser.utils.urlutils.UrlUtils.\
|
||||
join_url(self.path, file_name)
|
||||
a_file = False
|
||||
|
||||
if not import_template:
|
||||
log.error(_('Import "%(name)s" is not valid.') %
|
||||
{'name': import_uri_def})
|
||||
|
@ -556,3 +556,62 @@ class ToscaTemplateTest(TestCase):
|
||||
target.relationships
|
||||
except TypeError as error:
|
||||
self.fail(error)
|
||||
|
||||
def test_no_input(self):
|
||||
self.assertRaises(exception.ValidationError, ToscaTemplate, None,
|
||||
None, False, None)
|
||||
err_msg = (('No path or yaml_dict_tpl was provided. '
|
||||
'There is nothing to parse.'))
|
||||
exception.ExceptionCollector.assertExceptionMessage(ValueError,
|
||||
err_msg)
|
||||
|
||||
def test_path_and_yaml_dict_tpl_input(self):
|
||||
test_tpl = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"data/tosca_helloworld.yaml")
|
||||
|
||||
yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
|
||||
|
||||
tosca = ToscaTemplate(test_tpl, yaml_dict_tpl=yaml_dict_tpl)
|
||||
|
||||
self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
|
||||
|
||||
def test_yaml_dict_tpl_input(self):
|
||||
test_tpl = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"data/tosca_helloworld.yaml")
|
||||
|
||||
yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
|
||||
|
||||
tosca = ToscaTemplate(yaml_dict_tpl=yaml_dict_tpl)
|
||||
|
||||
self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
|
||||
|
||||
def test_yaml_dict_tpl_with_params_and_url_import(self):
|
||||
test_tpl = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"data/tosca_single_instance_wordpress_with_url_import.yaml")
|
||||
|
||||
yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
|
||||
|
||||
params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user',
|
||||
'db_root_pwd': 'mypasswd'}
|
||||
|
||||
tosca = ToscaTemplate(parsed_params=params,
|
||||
yaml_dict_tpl=yaml_dict_tpl)
|
||||
|
||||
self.assertEqual(tosca.version, "tosca_simple_yaml_1_0")
|
||||
|
||||
def test_yaml_dict_tpl_with_rel_import(self):
|
||||
test_tpl = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"data/tosca_single_instance_wordpress.yaml")
|
||||
|
||||
yaml_dict_tpl = toscaparser.utils.yamlparser.load_yaml(test_tpl)
|
||||
|
||||
self.assertRaises(exception.ValidationError, ToscaTemplate, None,
|
||||
None, False, yaml_dict_tpl)
|
||||
err_msg = (_('Relative file name "custom_types/wordpress.yaml" '
|
||||
'cannot be used in a pre-parsed input template.'))
|
||||
exception.ExceptionCollector.assertExceptionMessage(ImportError,
|
||||
err_msg)
|
||||
|
@ -51,13 +51,32 @@ class ToscaTemplate(object):
|
||||
VALID_TEMPLATE_VERSIONS = ['tosca_simple_yaml_1_0']
|
||||
|
||||
'''Load the template data.'''
|
||||
def __init__(self, path, parsed_params=None, a_file=True):
|
||||
def __init__(self, path=None, parsed_params=None, a_file=True,
|
||||
yaml_dict_tpl=None):
|
||||
ExceptionCollector.start()
|
||||
self.a_file = a_file
|
||||
self.input_path = path
|
||||
self.path = self._get_path(path)
|
||||
if self.path:
|
||||
self.tpl = YAML_LOADER(self.path, self.a_file)
|
||||
self.input_path = None
|
||||
self.path = None
|
||||
self.tpl = None
|
||||
if path:
|
||||
self.input_path = path
|
||||
self.path = self._get_path(path)
|
||||
if self.path:
|
||||
self.tpl = YAML_LOADER(self.path, self.a_file)
|
||||
if yaml_dict_tpl:
|
||||
msg = (_('Both path and yaml_dict_tpl arguments were '
|
||||
'provided. Using path and ignoring yaml_dict_tpl.'))
|
||||
log.info(msg)
|
||||
print(msg)
|
||||
else:
|
||||
if yaml_dict_tpl:
|
||||
self.tpl = yaml_dict_tpl
|
||||
else:
|
||||
ExceptionCollector.appendException(
|
||||
ValueError(_('No path or yaml_dict_tpl was provided. '
|
||||
'There is nothing to parse.')))
|
||||
|
||||
if self.tpl:
|
||||
self.parsed_params = parsed_params
|
||||
self._validate_field()
|
||||
self.version = self._tpl_version()
|
||||
@ -70,6 +89,7 @@ class ToscaTemplate(object):
|
||||
self.nodetemplates = self._nodetemplates()
|
||||
self.outputs = self._outputs()
|
||||
self.graph = ToscaGraph(self.nodetemplates)
|
||||
|
||||
ExceptionCollector.stop()
|
||||
self.verify_template()
|
||||
|
||||
@ -148,7 +168,7 @@ class ToscaTemplate(object):
|
||||
if imports:
|
||||
custom_defs = toscaparser.imports.\
|
||||
ImportsLoader(imports, self.path,
|
||||
type_defs).get_custom_defs()
|
||||
type_defs, self.tpl).get_custom_defs()
|
||||
if not custom_defs:
|
||||
return
|
||||
|
||||
@ -199,13 +219,23 @@ class ToscaTemplate(object):
|
||||
|
||||
def verify_template(self):
|
||||
if ExceptionCollector.exceptionsCaught():
|
||||
raise ValidationError(
|
||||
message=(_('\nThe input "%(path)s" failed validation with the '
|
||||
'following error(s): \n\n\t')
|
||||
% {'path': self.input_path}) +
|
||||
'\n\t'.join(ExceptionCollector.getExceptionsReport()))
|
||||
if self.input_path:
|
||||
raise ValidationError(
|
||||
message=(_('\nThe input "%(path)s" failed validation with '
|
||||
'the following error(s): \n\n\t')
|
||||
% {'path': self.input_path}) +
|
||||
'\n\t'.join(ExceptionCollector.getExceptionsReport()))
|
||||
else:
|
||||
raise ValidationError(
|
||||
message=_('\nThe pre-parsed input failed validation with '
|
||||
'the following error(s): \n\n\t') +
|
||||
'\n\t'.join(ExceptionCollector.getExceptionsReport()))
|
||||
else:
|
||||
msg = (_('The input "%(path)s" successfully passed validation.') %
|
||||
{'path': self.input_path})
|
||||
if self.input_path:
|
||||
msg = (_('The input "%(path)s" successfully passed '
|
||||
'validation.') % {'path': self.input_path})
|
||||
else:
|
||||
msg = _('The pre-parsed input successfully passed validation.')
|
||||
|
||||
log.info(msg)
|
||||
print(msg)
|
||||
|
Loading…
Reference in New Issue
Block a user