added unsafe toggle to vars_prompt (#49219)
* added unsafe toggle to vars_prompt fixes #47534
This commit is contained in:
parent
4a0fceaa3b
commit
4ac0c23db6
7 changed files with 51 additions and 10 deletions
2
changelogs/fragments/unsafe_prompt.yml
Normal file
2
changelogs/fragments/unsafe_prompt.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- added 'unsafe' keyword to vars_prompt so users can signal 'template unsafe' content
|
|
@ -89,6 +89,16 @@ Depending on your platform at most the following crypt schemes are supported:
|
|||
- *sha256_crypt* - SHA-256 Crypt
|
||||
- *sha512_crypt* - SHA-512 Crypt
|
||||
|
||||
.. versionadded:: 2.8
|
||||
|
||||
If you need to put in special characters (i.e `{%`) that might create templating errors, use the ``unsafe`` option::
|
||||
|
||||
vars_prompt:
|
||||
- name: "my_password_with_wierd_chars"
|
||||
prompt: "Enter password"
|
||||
unsafe: yes
|
||||
private: yes
|
||||
|
||||
.. seealso::
|
||||
|
||||
:doc:`playbooks`
|
||||
|
@ -101,6 +111,3 @@ Depending on your platform at most the following crypt schemes are supported:
|
|||
Have a question? Stop by the google group!
|
||||
`irc.freenode.net <http://irc.freenode.net>`_
|
||||
#ansible IRC chat channel
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -111,6 +111,7 @@ class PlaybookExecutor:
|
|||
templar = Templar(loader=self._loader, variables=all_vars)
|
||||
setattr(play, 'vars_prompt', templar.template(play.vars_prompt))
|
||||
|
||||
# FIXME: this should be a play 'sub object' like loop_control
|
||||
if play.vars_prompt:
|
||||
for var in play.vars_prompt:
|
||||
vname = var['name']
|
||||
|
@ -121,11 +122,13 @@ class PlaybookExecutor:
|
|||
encrypt = var.get("encrypt", None)
|
||||
salt_size = var.get("salt_size", None)
|
||||
salt = var.get("salt", None)
|
||||
unsafe = var.get("unsafe", None)
|
||||
|
||||
if vname not in self._variable_manager.extra_vars:
|
||||
if self._tqm:
|
||||
self._tqm.send_callback('v2_playbook_on_vars_prompt', vname, private, prompt, encrypt, confirm, salt_size, salt, default)
|
||||
play.vars[vname] = display.do_var_prompt(vname, private, prompt, encrypt, confirm, salt_size, salt, default)
|
||||
self._tqm.send_callback('v2_playbook_on_vars_prompt', vname, private, prompt, encrypt, confirm, salt_size, salt,
|
||||
default, unsafe)
|
||||
play.vars[vname] = display.do_var_prompt(vname, private, prompt, encrypt, confirm, salt_size, salt, default, unsafe)
|
||||
else: # we are either in --list-<option> or syntax check
|
||||
play.vars[vname] = default
|
||||
|
||||
|
|
|
@ -303,7 +303,7 @@ class CallbackBase(AnsiblePlugin):
|
|||
def playbook_on_task_start(self, name, is_conditional):
|
||||
pass
|
||||
|
||||
def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None):
|
||||
def playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None, unsafe=None):
|
||||
pass
|
||||
|
||||
def playbook_on_setup(self):
|
||||
|
@ -387,8 +387,8 @@ class CallbackBase(AnsiblePlugin):
|
|||
def v2_playbook_on_handler_task_start(self, task):
|
||||
pass # no v1 correspondence
|
||||
|
||||
def v2_playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None):
|
||||
self.playbook_on_vars_prompt(varname, private, prompt, encrypt, confirm, salt_size, salt, default)
|
||||
def v2_playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None, unsafe=None):
|
||||
self.playbook_on_vars_prompt(varname, private, prompt, encrypt, confirm, salt_size, salt, default, unsafe)
|
||||
|
||||
# FIXME: not called
|
||||
def v2_playbook_on_import_for_host(self, result, imported_file):
|
||||
|
|
|
@ -39,7 +39,7 @@ from ansible.module_utils._text import to_bytes, to_text
|
|||
from ansible.module_utils.six import with_metaclass
|
||||
from ansible.utils.color import stringc
|
||||
from ansible.utils.singleton import Singleton
|
||||
|
||||
from ansible.utils.unsafe_proxy import wrap_var
|
||||
|
||||
try:
|
||||
# Python 2
|
||||
|
@ -305,7 +305,7 @@ class Display(with_metaclass(Singleton, object)):
|
|||
else:
|
||||
return input(prompt_string)
|
||||
|
||||
def do_var_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None):
|
||||
def do_var_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None, unsafe=None):
|
||||
|
||||
result = None
|
||||
if sys.__stdin__.isatty():
|
||||
|
@ -343,6 +343,9 @@ class Display(with_metaclass(Singleton, object)):
|
|||
|
||||
# handle utf-8 chars
|
||||
result = to_text(result, errors='surrogate_or_strict')
|
||||
|
||||
if unsafe:
|
||||
result = wrap_var(result)
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -109,6 +109,12 @@ tests = [
|
|||
'test_spec': [
|
||||
[('prompting for host:', 'testhost\r')],
|
||||
r'testhost.*ok=1']},
|
||||
|
||||
# Test play unsafe toggle
|
||||
{'playbook': 'unsafe.yml',
|
||||
'test_spec': [
|
||||
[('prompting for variable:', '{{whole}}\r')],
|
||||
r'testhost.*ok=2']},
|
||||
]
|
||||
|
||||
for t in tests:
|
||||
|
|
20
test/integration/targets/vars_prompt/unsafe.yml
Normal file
20
test/integration/targets/vars_prompt/unsafe.yml
Normal file
|
@ -0,0 +1,20 @@
|
|||
- name: Test vars_prompt unsafe
|
||||
hosts: testhost
|
||||
become: no
|
||||
gather_facts: no
|
||||
vars:
|
||||
whole: INVALID
|
||||
vars_prompt:
|
||||
- name: input
|
||||
prompt: prompting for variable
|
||||
unsafe: true
|
||||
|
||||
tasks:
|
||||
- name:
|
||||
assert:
|
||||
that:
|
||||
- input != whole
|
||||
- input != 'INVALID'
|
||||
|
||||
- debug:
|
||||
var: input
|
Loading…
Reference in a new issue