diff --git a/heatclient/common/template_utils.py b/heatclient/common/template_utils.py index 4fa72d86..2134a761 100644 --- a/heatclient/common/template_utils.py +++ b/heatclient/common/template_utils.py @@ -30,6 +30,7 @@ def get_template_contents(template_file=None, template_url=None, template_object=None, object_request=None, files=None, existing=False): + is_object = False # Transform a bare file path to a file:// URL. if template_file: template_url = utils.normalise_file_path_to_url(template_file) @@ -38,6 +39,7 @@ def get_template_contents(template_file=None, template_url=None, tpl = request.urlopen(template_url).read() elif template_object: + is_object = True template_url = template_object tpl = object_request and object_request('GET', template_object) @@ -66,11 +68,13 @@ def get_template_contents(template_file=None, template_url=None, tmpl_base_url = utils.base_url_for_url(template_url) if files is None: files = {} - resolve_template_get_files(template, files, tmpl_base_url) + resolve_template_get_files(template, files, tmpl_base_url, is_object, + object_request) return files, template -def resolve_template_get_files(template, files, template_base_url): +def resolve_template_get_files(template, files, template_base_url, + is_object=False, object_request=None): def ignore_if(key, value): if key != 'get_file' and key != 'type': @@ -86,7 +90,7 @@ def resolve_template_get_files(template, files, template_base_url): return isinstance(value, (dict, list)) get_file_contents(template, files, template_base_url, - ignore_if, recurse_if) + ignore_if, recurse_if, is_object, object_request) def is_template(file_content): @@ -100,7 +104,8 @@ def is_template(file_content): def get_file_contents(from_data, files, base_url=None, - ignore_if=None, recurse_if=None): + ignore_if=None, recurse_if=None, + is_object=False, object_request=None): if recurse_if and recurse_if(from_data): if isinstance(from_data, dict): @@ -108,7 +113,8 @@ def get_file_contents(from_data, files, base_url=None, else: recurse_data = from_data for value in recurse_data: - get_file_contents(value, files, base_url, ignore_if, recurse_if) + get_file_contents(value, files, base_url, ignore_if, recurse_if, + is_object, object_request) if isinstance(from_data, dict): for key, value in six.iteritems(from_data): @@ -120,10 +126,18 @@ def get_file_contents(from_data, files, base_url=None, str_url = parse.urljoin(base_url, value) if str_url not in files: - file_content = utils.read_url_content(str_url) + if is_object and object_request: + file_content = object_request('GET', str_url) + else: + file_content = utils.read_url_content(str_url) if is_template(file_content): - template = get_template_contents( - template_url=str_url, files=files)[1] + if is_object: + template = get_template_contents( + template_object=str_url, files=files, + object_request=object_request)[1] + else: + template = get_template_contents( + template_url=str_url, files=files)[1] file_content = jsonutils.dumps(template) files[str_url] = file_content # replace the data value with the normalised absolute URL diff --git a/heatclient/tests/unit/test_template_utils.py b/heatclient/tests/unit/test_template_utils.py index 5e32b896..29935480 100644 --- a/heatclient/tests/unit/test_template_utils.py +++ b/heatclient/tests/unit/test_template_utils.py @@ -493,6 +493,33 @@ class TestGetTemplateContents(testtools.TestCase): self.assertEqual({}, files) self.assertTrue(self.object_requested) + def test_get_nested_stack_template_contents_object(self): + tmpl = ('{"heat_template_version": "2016-04-08",' + '"resources": {' + '"FooBar": {' + '"type": "foo/bar.yaml"}}}') + url = 'http://no.where/path/to/a.yaml' + self.m.ReplayAll() + + self.object_requested = False + + def object_request(method, object_url): + self.object_requested = True + self.assertEqual('GET', method) + self.assertTrue(object_url.startswith("http://no.where/path/to/")) + if object_url == url: + return tmpl + else: + return '{"heat_template_version": "2016-04-08"}' + + files, tmpl_parsed = template_utils.get_template_contents( + template_object=url, + object_request=object_request) + + self.assertEqual(files['http://no.where/path/to/foo/bar.yaml'], + '{"heat_template_version": "2016-04-08"}') + self.assertTrue(self.object_requested) + def check_non_utf8_content(self, filename, content): base_url = 'file:///tmp' url = '%s/%s' % (base_url, filename)