diff --git a/examples/playbooks/prompts.yml b/examples/playbooks/prompts.yml index 1a6de1e886..bb034d62c9 100644 --- a/examples/playbooks/prompts.yml +++ b/examples/playbooks/prompts.yml @@ -12,22 +12,35 @@ this_is_a_regular_var: 'moo' so_is_this: 'quack' -# prompted variables are a list of variable names and a description -# that will be presented to the user. -# # alternatively, they can ALSO be passed in from the outside: # ansible-playbook foo.yml --extra-vars="foo=100 bar=101" # or through external inventory scripts (see online API docs) +# prompted variables are a list of variable names and a description +# that will be presented to the user, or a list of variable dictionaries +# with the following accepted keys / value types: +# 'name' / text +# 'prompt' / text (optional) +# 'private' / boolean (optional) + +# prompted variables as key/value pairs: vars_prompt: release_version: "product release version" - tasks: +# prompted variables as a list of variable dictionaries: +# vars_prompt: +# - name: "some_password" +# prompt: "Enter password: " +# private: True +# - name: "release_version" +# prompt: "Product release version: " +# private: False # this is just a simple example to show that vars_prompt works, but # you might ask for a tag to use with the git module or perhaps # a package version to use with the yum module. + tasks: - name: imagine this did something interesting with $release_version action: shell echo foo >> /tmp/$release_version-$alpha diff --git a/lib/ansible/callbacks.py b/lib/ansible/callbacks.py index d4e26fc86d..ce06af6609 100644 --- a/lib/ansible/callbacks.py +++ b/lib/ansible/callbacks.py @@ -365,9 +365,12 @@ class PlaybookCallbacks(object): msg = "NOTIFIED: [%s]" % name print banner(msg) - def on_vars_prompt(self, varname, private=True): + def on_vars_prompt(self, varname, private=True, prompt=None): - msg = 'input for %s: ' % varname + if prompt: + msg = prompt + else: + msg = 'input for %s: ' % varname if private: return getpass.getpass(msg) return raw_input(msg) diff --git a/lib/ansible/playbook/play.py b/lib/ansible/playbook/play.py index a6fe723e2f..9a640aab52 100644 --- a/lib/ansible/playbook/play.py +++ b/lib/ansible/playbook/play.py @@ -155,10 +155,26 @@ class Play(object): else: vars.update(self.vars) - if type(self.vars_prompt) != dict: - raise errors.AnsibleError("'vars_prompt' section must contain only key/value pairs") - for vname in self.vars_prompt: - vars[vname] = self.playbook.callbacks.on_vars_prompt(vname) + if type(self.vars_prompt) == list: + for var in self.vars_prompt: + try: + vname = var.get("name") + except KeyError: + raise errors.AnsibleError("A variable dictionary in 'vars_prompt' must always have a 'name' key") + if not ((vname[0].isalpha() or vname[0] == '_') and vname.replace('_','').isalnum()): + raise errors.AnsibleError("'%s' cannot be used as a variable name. Variable names must consist of" + " a letter or underscore, followed by a string of letters, numbers, and underscores" + % vname) + prompt = var.get("prompt", None) + private = var.get("private", True) + + vars[vname] = self.playbook.callbacks.on_vars_prompt(vname, private, prompt) + elif type(self.vars_prompt) == dict: + for vname in self.vars_prompt: + vars[vname] = self.playbook.callbacks.on_vars_prompt(vname) + else: + raise errors.AnsibleError("'vars_prompt' section must contain either key/value pairs or a list" + " of variable dictionaries (see docs for accepted dictionary keys)") results = self.playbook.extra_vars.copy() results.update(vars)