From c717934b7e355b5ec2cf899898011c2f5f1132be Mon Sep 17 00:00:00 2001 From: Petros Moisiadis Date: Tue, 24 Jul 2012 17:43:29 +0300 Subject: [PATCH] Improved 'vars_prompt' syntax to support prompt text and (non-)private input An example of the new syntax: vars_prompt: - name: 'secret_variable_name" prompt: "Enter secret value: " private: "yes" - name: "nonsecret_variable_name" prompt: "Enter non-secret value: " private: "no" --- examples/playbooks/prompts.yml | 21 +++++++++++++++++---- lib/ansible/callbacks.py | 7 +++++-- lib/ansible/playbook/play.py | 24 ++++++++++++++++++++---- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/examples/playbooks/prompts.yml b/examples/playbooks/prompts.yml index 1a6de1e8867..bb034d62c9f 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 d4e26fc86d6..ce06af66094 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 a6fe723e2fa..9a640aab52c 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)