From e81947c3b4ad4eb93c5163ba9879e0394d00bb72 Mon Sep 17 00:00:00 2001 From: James Cammarata Date: Wed, 9 Sep 2015 17:52:44 -0400 Subject: [PATCH] Fix vars_prompt short form support (and mark deprecated) --- lib/ansible/executor/playbook_executor.py | 4 --- lib/ansible/playbook/play.py | 33 ++++++++++++++++++++--- lib/ansible/vars/__init__.py | 28 ++++++++++++++++--- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/lib/ansible/executor/playbook_executor.py b/lib/ansible/executor/playbook_executor.py index 2b127bb429..3be27c47dd 100644 --- a/lib/ansible/executor/playbook_executor.py +++ b/lib/ansible/executor/playbook_executor.py @@ -88,14 +88,10 @@ class PlaybookExecutor: if play.vars_prompt: for var in play.vars_prompt: - if 'name' not in var: - raise AnsibleError("'vars_prompt' item is missing 'name:'", obj=play._ds) - vname = var['name'] prompt = var.get("prompt", vname) default = var.get("default", None) private = var.get("private", True) - confirm = var.get("confirm", False) encrypt = var.get("encrypt", None) salt_size = var.get("salt_size", None) diff --git a/lib/ansible/playbook/play.py b/lib/ansible/playbook/play.py index 01847b0a5d..5324677651 100644 --- a/lib/ansible/playbook/play.py +++ b/lib/ansible/playbook/play.py @@ -31,10 +31,18 @@ from ansible.playbook.helpers import load_list_of_blocks, load_list_of_roles from ansible.playbook.role import Role from ansible.playbook.taggable import Taggable from ansible.playbook.task import Task +from ansible.vars import preprocess_vars __all__ = ['Play'] +try: + from __main__ import display + display = display +except ImportError: + from ansible.utils.display import Display + display = Display() + class Play(Base, Taggable, Become): @@ -120,9 +128,6 @@ class Play(Base, Taggable, Become): ds['remote_user'] = ds['user'] del ds['user'] - if 'vars_prompt' in ds and not isinstance(ds['vars_prompt'], list): - ds['vars_prompt'] = [ ds['vars_prompt'] ] - return super(Play, self).preprocess_data(ds) def _load_hosts(self, attr, ds): @@ -191,8 +196,28 @@ class Play(Base, Taggable, Become): roles.append(Role.load(ri, play=self)) return roles - # FIXME: post_validation needs to ensure that become/su/sudo have only 1 set + def _load_vars_prompt(self, attr, ds): + new_ds = preprocess_vars(ds) + vars_prompts = [] + for prompt_data in new_ds: + if 'name' not in prompt_data: + self._display.deprecated("Using the 'short form' for vars_prompt has been deprecated") + for vname, prompt in prompt_data.iteritems(): + vars_prompts.append(dict( + name = vname, + prompt = prompt, + default = None, + private = None, + confirm = None, + encrypt = None, + salt_size = None, + salt = None, + )) + else: + vars_prompts.append(prompt_data) + return vars_prompts + # FIXME: post_validation needs to ensure that become/su/sudo have only 1 set def _compile_roles(self): ''' Handles the role compilation step, returning a flat list of tasks diff --git a/lib/ansible/vars/__init__.py b/lib/ansible/vars/__init__.py index 0fe4b3fdb3..491b99a804 100644 --- a/lib/ansible/vars/__init__.py +++ b/lib/ansible/vars/__init__.py @@ -44,6 +44,26 @@ from ansible.vars.unsafe_proxy import UnsafeProxy CACHED_VARS = dict() +def preprocess_vars(a): + ''' + Ensures that vars contained in the parameter passed in are + returned as a list of dictionaries, to ensure for instance + that vars loaded from a file conform to an expected state. + ''' + + if a is None: + return None + elif not isinstance(a, list): + data = [ a ] + else: + data = a + + for item in data: + if not isinstance(item, MutableMapping): + raise AnsibleError("variable files must contain either a dictionary of variables, or a list of dictionaries. Got: %s (%s)" % (a, type(a))) + + return data + class VariableManager: def __init__(self): @@ -157,14 +177,14 @@ class VariableManager: # then we merge in the special 'all' group_vars first, if they exist if 'all' in self._group_vars_files: - data = self._preprocess_vars(self._group_vars_files['all']) + data = preprocess_vars(self._group_vars_files['all']) for item in data: all_vars = combine_vars(all_vars, item) for group in host.get_groups(): if group.name in self._group_vars_files and group.name != 'all': for data in self._group_vars_files[group.name]: - data = self._preprocess_vars(data) + data = preprocess_vars(data) for item in data: all_vars = combine_vars(all_vars, item) @@ -175,7 +195,7 @@ class VariableManager: host_name = host.get_name() if host_name in self._host_vars_files: for data in self._host_vars_files[host_name]: - data = self._preprocess_vars(data) + data = preprocess_vars(data) for item in data: all_vars = combine_vars(all_vars, item) @@ -211,7 +231,7 @@ class VariableManager: # as soon as we read one from the list. If none are found, we # raise an error, which is silently ignored at this point. for vars_file in vars_file_list: - data = self._preprocess_vars(loader.load_from_file(vars_file)) + data = preprocess_vars(loader.load_from_file(vars_file)) if data is not None: for item in data: all_vars = combine_vars(all_vars, item)