From bc860bf7c62176c927602e969c1f55d4b72277b8 Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Fri, 8 Jan 2016 16:48:34 -0500 Subject: [PATCH] Update template_utils to support object env's This patch updates several functions in template_utils.py so that they support loading environments from Swift containers (objects) in the same manner we currently load template files. The primary interfaces is process_multiple_environments_and_files which contains two new parameters: -env_path_is_object: a function to determine if the URL is an object -object_request: a function used to load the object Change-Id: If60a3ad44531bc6ca4f7a03a77f236173d3137ba --- heatclient/common/template_utils.py | 35 ++++++++++++++---- heatclient/tests/unit/test_template_utils.py | 39 ++++++++++++++++++++ 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/heatclient/common/template_utils.py b/heatclient/common/template_utils.py index aa4583c0..a14f35cc 100644 --- a/heatclient/common/template_utils.py +++ b/heatclient/common/template_utils.py @@ -187,14 +187,19 @@ def deep_update(old, new): def process_multiple_environments_and_files(env_paths=None, template=None, - template_url=None): + template_url=None, + env_path_is_object=None, + object_request=None): + merged_files = {} merged_env = {} if env_paths: for env_path in env_paths: files, env = process_environment_and_files(env_path, template, - template_url) + template_url, + env_path_is_object, + object_request) # 'files' looks like {"filename1": contents, "filename2": contents} # so a simple update is enough for merging @@ -208,11 +213,24 @@ def process_multiple_environments_and_files(env_paths=None, template=None, def process_environment_and_files(env_path=None, template=None, - template_url=None): + template_url=None, env_path_is_object=None, + object_request=None): files = {} env = {} - if env_path: + is_object = env_path_is_object and env_path_is_object(env_path) + + if is_object: + raw_env = object_request and object_request('GET', env_path) + env = environment_format.parse(raw_env) + env_base_url = utils.base_url_for_url(env_path) + + resolve_environment_urls( + env.get('resource_registry'), + files, + env_base_url, is_object=True, object_request=object_request) + + elif env_path: env_url = utils.normalise_file_path_to_url(env_path) env_base_url = utils.base_url_for_url(env_url) raw_env = request.urlopen(env_url).read() @@ -226,7 +244,8 @@ def process_environment_and_files(env_path=None, template=None, return files, env -def resolve_environment_urls(resource_registry, files, env_base_url): +def resolve_environment_urls(resource_registry, files, env_base_url, + is_object=False, object_request=None): if resource_registry is None: return @@ -245,12 +264,14 @@ def resolve_environment_urls(resource_registry, files, env_base_url): if key == 'hooks': return True - get_file_contents(rr, files, base_url, ignore_if) + get_file_contents(rr, files, base_url, ignore_if, + is_object=is_object, object_request=object_request) for res_name, res_dict in six.iteritems(rr.get('resources', {})): res_base_url = res_dict.get('base_url', base_url) get_file_contents( - res_dict, files, res_base_url, ignore_if) + res_dict, files, res_base_url, ignore_if, + is_object=is_object, object_request=object_request) def hooks_to_env(env, arg_hooks, hook): diff --git a/heatclient/tests/unit/test_template_utils.py b/heatclient/tests/unit/test_template_utils.py index 29935480..f82aa891 100644 --- a/heatclient/tests/unit/test_template_utils.py +++ b/heatclient/tests/unit/test_template_utils.py @@ -313,6 +313,45 @@ class ShellEnvironmentTest(testtools.TestCase): self.assertEqual({}, env) self.assertEqual({}, files) + def test_process_multiple_environments_and_files_from_object(self): + + env_object = 'http://no.where/path/to/env.yaml' + env1 = b''' + parameters: + "param1": "value1" + resource_registry: + "OS::Thingy1": "b/a.yaml" + ''' + + self.m.ReplayAll() + + self.object_requested = False + + def env_path_is_object(object_url): + return True + + 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 == env_object: + return env1 + else: + return self.template_a + + files, env = template_utils.process_multiple_environments_and_files( + env_paths=[env_object], env_path_is_object=env_path_is_object, + object_request=object_request) + self.assertEqual( + { + 'resource_registry': { + 'OS::Thingy1': 'http://no.where/path/to/b/a.yaml'}, + 'parameters': {'param1': 'value1'} + }, + env) + self.assertEqual(self.template_a.decode('utf-8'), + files['http://no.where/path/to/b/a.yaml']) + def test_global_files(self): url = 'file:///home/b/a.yaml' env = '''