diff options
author | rabi <ramishra@redhat.com> | 2018-03-12 07:52:33 +0530 |
---|---|---|
committer | rabi <ramishra@redhat.com> | 2018-08-29 18:32:03 +0530 |
commit | bd2bfaa514cfc6769b74bd0c213c58bcc1eef6ea (patch) | |
tree | 0d68079bbefb6860678c1840f10fe255adb527d9 /heatclient | |
parent | 38e03316b12201e20dca1ed3307853babd6acb8f (diff) | |
download | python-heatclient-bd2bfaa514cfc6769b74bd0c213c58bcc1eef6ea.tar.gz |
Add files-container option for stack create and update
If files-container option is specified:
- All template/env files would be fetched by the heat engine
relative to the files_container and no local files other
than the root template would be sent to server.
- Relative path of environment files would be sent in the
environment_files list.
Also adds the option to template validate.
Change-Id: I1a703ab8798a003365be650886bb78be5af472b7
Story: #1755453
Task: 19319
Diffstat (limited to 'heatclient')
-rw-r--r-- | heatclient/common/template_utils.py | 62 | ||||
-rw-r--r-- | heatclient/osc/v1/stack.py | 32 | ||||
-rw-r--r-- | heatclient/osc/v1/template.py | 16 | ||||
-rw-r--r-- | heatclient/tests/unit/test_template_utils.py | 12 |
4 files changed, 91 insertions, 31 deletions
diff --git a/heatclient/common/template_utils.py b/heatclient/common/template_utils.py index cdb330a..2c66f2b 100644 --- a/heatclient/common/template_utils.py +++ b/heatclient/common/template_utils.py @@ -27,7 +27,8 @@ from heatclient.common import utils from heatclient import exc -def process_template_path(template_path, object_request=None, existing=False): +def process_template_path(template_path, object_request=None, + existing=False, fetch_child=True): """Read template from template path. Attempt to read template first as a file or url. If that is unsuccessful, @@ -37,17 +38,20 @@ def process_template_path(template_path, object_request=None, existing=False): :param object_request: custom object request function used to get template if local or uri path fails :param existing: if the current stack's template should be used + :param fetch_child: Whether to fetch the child templates :returns: get_file dict and template contents :raises: error.URLError """ try: return get_template_contents(template_file=template_path, - existing=existing) + existing=existing, + fetch_child=fetch_child) except error.URLError as template_file_exc: try: return get_template_contents(template_object=template_path, object_request=object_request, - existing=existing) + existing=existing, + fetch_child=fetch_child) except exc.HTTPNotFound: # The initial exception gives the user better failure context. raise template_file_exc @@ -55,7 +59,8 @@ def process_template_path(template_path, object_request=None, existing=False): def get_template_contents(template_file=None, template_url=None, template_object=None, object_request=None, - files=None, existing=False): + files=None, existing=False, + fetch_child=True): is_object = False # Transform a bare file path to a file:// URL. @@ -93,12 +98,13 @@ def get_template_contents(template_file=None, template_url=None, except ValueError as e: raise exc.CommandError(_('Error parsing template %(url)s %(error)s') % {'url': template_url, 'error': e}) - - tmpl_base_url = utils.base_url_for_url(template_url) if files is None: files = {} - resolve_template_get_files(template, files, tmpl_base_url, is_object, - object_request) + + if fetch_child: + tmpl_base_url = utils.base_url_for_url(template_url) + resolve_template_get_files(template, files, tmpl_base_url, is_object, + object_request) return files, template @@ -212,7 +218,8 @@ def process_multiple_environments_and_files(env_paths=None, template=None, template_url=None, env_path_is_object=None, object_request=None, - env_list_tracker=None): + env_list_tracker=None, + fetch_env_files=True): """Reads one or more environment files. Reads in each specified environment file and returns a dictionary @@ -239,6 +246,7 @@ def process_multiple_environments_and_files(env_paths=None, template=None, :type env_list_tracker: list or None :return: tuple of files dict and a dict of the consolidated environment :rtype: tuple + :param fetch_env_files: fetch env_files or leave it to server """ merged_files = {} merged_env = {} @@ -249,24 +257,28 @@ def process_multiple_environments_and_files(env_paths=None, template=None, if env_paths: for env_path in env_paths: - files, env = process_environment_and_files( - env_path=env_path, - template=template, - template_url=template_url, - env_path_is_object=env_path_is_object, - object_request=object_request, - include_env_in_files=include_env_in_files) - - # 'files' looks like {"filename1": contents, "filename2": contents} - # so a simple update is enough for merging - merged_files.update(files) - - # 'env' can be a deeply nested dictionary, so a simple update is - # not enough - merged_env = deep_update(merged_env, env) + if fetch_env_files: + files, env = process_environment_and_files( + env_path=env_path, + template=template, + template_url=template_url, + env_path_is_object=env_path_is_object, + object_request=object_request, + include_env_in_files=include_env_in_files) + + # 'files' looks like: + # {"filename1": contents, "filename2": contents} + # so a simple update is enough for merging + merged_files.update(files) + + # 'env' can be a deeply nested dictionary, so a simple + # update is not enough + merged_env = deep_update(merged_env, env) + env_url = utils.normalise_file_path_to_url(env_path) + else: + env_url = env_path if env_list_tracker is not None: - env_url = utils.normalise_file_path_to_url(env_path) env_list_tracker.append(env_url) return merged_files, merged_env diff --git a/heatclient/osc/v1/stack.py b/heatclient/osc/v1/stack.py index 3817bea..318777a 100644 --- a/heatclient/osc/v1/stack.py +++ b/heatclient/osc/v1/stack.py @@ -47,6 +47,13 @@ class CreateStack(command.ShowOne): help=_('Path to the environment. Can be specified multiple times') ) parser.add_argument( + '-s', '--files-container', + metavar='<files-container>', + help=_('Swift files container name. Local files other than ' + 'root template would be ignored. If other files are not ' + 'found in swift, heat engine would raise an error.') + ) + parser.add_argument( '--timeout', metavar='<timeout>', type=int, @@ -121,13 +128,15 @@ class CreateStack(command.ShowOne): tpl_files, template = template_utils.process_template_path( parsed_args.template, - object_request=http.authenticated_fetcher(client)) + object_request=http.authenticated_fetcher(client), + fetch_child=parsed_args.files_container is None) env_files_list = [] env_files, env = ( template_utils.process_multiple_environments_and_files( env_paths=parsed_args.environment, - env_list_tracker=env_files_list)) + env_list_tracker=env_files_list, + fetch_env_files=parsed_args.files_container is None)) parameters = heat_utils.format_all_parameters( parsed_args.parameter, @@ -151,6 +160,9 @@ class CreateStack(command.ShowOne): if env_files_list: fields['environment_files'] = env_files_list + if parsed_args.files_container: + fields['files_container'] = parsed_args.files_container + if parsed_args.tags: fields['tags'] = parsed_args.tags if parsed_args.timeout: @@ -202,6 +214,13 @@ class UpdateStack(command.ShowOne): help=_('Path to the template') ) parser.add_argument( + '-s', '--files-container', + metavar='<files-container>', + help=_('Swift files container name. Local files other than ' + 'root template would be ignored. If other files are not ' + 'found in swift, heat engine would raise an error.') + ) + parser.add_argument( '-e', '--environment', metavar='<environment>', action='append', help=_('Path to the environment. Can be specified multiple times') @@ -298,13 +317,15 @@ class UpdateStack(command.ShowOne): tpl_files, template = template_utils.process_template_path( parsed_args.template, object_request=http.authenticated_fetcher(client), - existing=parsed_args.existing) + existing=parsed_args.existing, + fetch_child=parsed_args.files_container is None) env_files_list = [] env_files, env = ( template_utils.process_multiple_environments_and_files( env_paths=parsed_args.environment, - env_list_tracker=env_files_list)) + env_list_tracker=env_files_list, + fetch_env_files=parsed_args.files_container is None)) parameters = heat_utils.format_all_parameters( parsed_args.parameter, @@ -328,6 +349,9 @@ class UpdateStack(command.ShowOne): if env_files_list: fields['environment_files'] = env_files_list + if parsed_args.files_container: + fields['files_container'] = parsed_args.files_container + if parsed_args.tags: fields['tags'] = parsed_args.tags if parsed_args.timeout: diff --git a/heatclient/osc/v1/template.py b/heatclient/osc/v1/template.py index c501812..f25263e 100644 --- a/heatclient/osc/v1/template.py +++ b/heatclient/osc/v1/template.py @@ -123,6 +123,13 @@ class Validate(format_utils.YamlFormat): 'specified multiple times') ) parser.add_argument( + '-s', '--files-container', + metavar='<files-container>', + help=_('Swift files container name. Local files other than ' + 'root template would be ignored. If other files are not ' + 'found in swift, heat engine would raise an error.') + ) + parser.add_argument( '--ignore-errors', metavar='<error1,error2,...>', help=_('List of heat errors to ignore') @@ -145,11 +152,13 @@ class Validate(format_utils.YamlFormat): def _validate(heat_client, args): tpl_files, template = template_utils.process_template_path( args.template, - object_request=http.authenticated_fetcher(heat_client)) + object_request=http.authenticated_fetcher(heat_client), + fetch_child=args.files_container is None) env_files_list = [] env_files, env = template_utils.process_multiple_environments_and_files( - env_paths=args.environment, env_list_tracker=env_files_list) + env_paths=args.environment, env_list_tracker=env_files_list, + fetch_env_files=args.files_container is None) fields = { 'template': template, @@ -168,6 +177,9 @@ def _validate(heat_client, args): if args.show_nested: fields['show_nested'] = args.show_nested + if args.files_container: + fields['files_container'] = args.files_container + validation = heat_client.stacks.validate(**fields) data = list(six.itervalues(validation)) columns = list(six.iterkeys(validation)) diff --git a/heatclient/tests/unit/test_template_utils.py b/heatclient/tests/unit/test_template_utils.py index e4303c6..81ef955 100644 --- a/heatclient/tests/unit/test_template_utils.py +++ b/heatclient/tests/unit/test_template_utils.py @@ -127,6 +127,18 @@ class ShellEnvironmentTest(testtools.TestCase): mock.call('file:///home/my/dir/a.yaml') ]) + def test_process_multiple_environment_files_container(self): + + env_list_tracker = [] + env_paths = ['/home/my/dir/env.yaml'] + files, env = template_utils.process_multiple_environments_and_files( + env_paths, env_list_tracker=env_list_tracker, + fetch_env_files=False) + + self.assertEqual(env_paths, env_list_tracker) + self.assertEqual({}, files) + self.assertEqual({}, env) + @mock.patch('six.moves.urllib.request.urlopen') def test_process_environment_relative_file_up(self, mock_url): |