summaryrefslogtreecommitdiff
path: root/heatclient
diff options
context:
space:
mode:
authorrabi <ramishra@redhat.com>2018-03-12 07:52:33 +0530
committerrabi <ramishra@redhat.com>2018-08-29 18:32:03 +0530
commitbd2bfaa514cfc6769b74bd0c213c58bcc1eef6ea (patch)
tree0d68079bbefb6860678c1840f10fe255adb527d9 /heatclient
parent38e03316b12201e20dca1ed3307853babd6acb8f (diff)
downloadpython-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.py62
-rw-r--r--heatclient/osc/v1/stack.py32
-rw-r--r--heatclient/osc/v1/template.py16
-rw-r--r--heatclient/tests/unit/test_template_utils.py12
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):