From ed00741a01ed4eb935797afc74cabf6ce0a0e7fa Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Thu, 17 Nov 2016 13:18:29 -0800 Subject: [PATCH] Mcsalgado's change to use shlex.quote instead of pipes.quote (#18534) * Replace pipes.quote for shlex_quote * More migration of pipes.quote to shlex_quote Note that we cannot yet move module code over. Modules have six-1.4 bundled which does not have shlex_quote. This shouldn't be a problem as the function is still importable from pipes.quote. It's just that this has become an implementation detail that makes us want to import from shlex instead. Once we get rid of the python2.4 dependency we can update to a newer version of bundled six module-side and then we're free to use shlex_quote everywhere. --- lib/ansible/playbook/play_context.py | 10 ++++----- lib/ansible/plugins/action/__init__.py | 9 ++++---- lib/ansible/plugins/action/async.py | 6 ++---- lib/ansible/plugins/connection/chroot.py | 6 +++--- lib/ansible/plugins/connection/docker.py | 4 ++-- lib/ansible/plugins/connection/jail.py | 6 +++--- lib/ansible/plugins/connection/libvirt_lxc.py | 6 +++--- lib/ansible/plugins/connection/ssh.py | 8 +++---- lib/ansible/plugins/connection/zone.py | 6 +++--- lib/ansible/plugins/filter/core.py | 4 ++-- lib/ansible/plugins/shell/__init__.py | 21 ++++++++++--------- lib/ansible/plugins/shell/fish.py | 9 ++++---- lib/ansible/plugins/shell/sh.py | 4 ++-- test/units/playbook/test_play_context.py | 4 ++-- test/units/plugins/action/test_action.py | 4 ++-- test/units/plugins/connection/test_ssh.py | 18 ++++++++-------- 16 files changed, 62 insertions(+), 63 deletions(-) diff --git a/lib/ansible/playbook/play_context.py b/lib/ansible/playbook/play_context.py index f5b9434200..c50486e5ea 100644 --- a/lib/ansible/playbook/play_context.py +++ b/lib/ansible/playbook/play_context.py @@ -22,13 +22,13 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type import os -import pipes import pwd import random import re import string from ansible.compat.six import iteritems, string_types +from ansible.compat.six.moves import shlex_quote from ansible import constants as C from ansible.errors import AnsibleError from ansible.module_utils._text import to_bytes @@ -467,7 +467,7 @@ class PlayContext(Base): becomecmd = None randbits = ''.join(random.choice(string.ascii_lowercase) for x in range(32)) success_key = 'BECOME-SUCCESS-%s' % randbits - success_cmd = pipes.quote('echo %s; %s' % (success_key, cmd)) + success_cmd = shlex_quote('echo %s; %s' % (success_key, cmd)) if executable: command = '%s -c %s' % (executable, success_cmd) @@ -496,7 +496,7 @@ class PlayContext(Base): # done for older versions of sudo that do not support the option. # # Passing a quoted compound command to sudo (or sudo -s) - # directly doesn't work, so we shellquote it with pipes.quote() + # directly doesn't work, so we shellquote it with shlex_quote() # and pass the quoted string to the user's shell. # force quick error if password is required but not supplied, should prevent sudo hangs. @@ -518,7 +518,7 @@ class PlayContext(Base): return bool(b_SU_PROMPT_LOCALIZATIONS_RE.match(b_data)) prompt = detect_su_prompt - becomecmd = '%s %s %s -c %s' % (exe, flags, self.become_user, pipes.quote(command)) + becomecmd = '%s %s %s -c %s' % (exe, flags, self.become_user, shlex_quote(command)) elif self.become_method == 'pbrun': @@ -562,7 +562,7 @@ class PlayContext(Base): exe = self.become_exe or 'dzdo' if self.become_pass: prompt = '[dzdo via ansible, key=%s] password: ' % randbits - becomecmd = '%s -p %s -u %s %s' % (exe, pipes.quote(prompt), self.become_user, command) + becomecmd = '%s -p %s -u %s %s' % (exe, shlex_quote(prompt), self.become_user, command) else: becomecmd = '%s -u %s %s' % (exe, self.become_user, command) diff --git a/lib/ansible/plugins/action/__init__.py b/lib/ansible/plugins/action/__init__.py index d2ef5988e3..c59b6bdd90 100644 --- a/lib/ansible/plugins/action/__init__.py +++ b/lib/ansible/plugins/action/__init__.py @@ -22,7 +22,6 @@ __metaclass__ = type import base64 import json import os -import pipes import random import re import stat @@ -30,9 +29,9 @@ import tempfile import time from abc import ABCMeta, abstractmethod -from ansible.compat.six import binary_type, text_type, iteritems, with_metaclass - from ansible import constants as C +from ansible.compat.six import binary_type, text_type, iteritems, with_metaclass +from ansible.compat.six.moves import shlex_quote from ansible.errors import AnsibleError, AnsibleConnectionFailure from ansible.executor.module_common import modify_module from ansible.module_utils._text import to_bytes, to_native, to_text @@ -596,7 +595,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): # the remote system, which can be read and parsed by the module args_data = "" for k,v in iteritems(module_args): - args_data += '%s=%s ' % (k, pipes.quote(text_type(v))) + args_data += '%s=%s ' % (k, shlex_quote(text_type(v))) self._transfer_data(args_file_path, args_data) elif module_style in ('non_native_want_json', 'binary'): self._transfer_data(args_file_path, json.dumps(module_args)) @@ -748,7 +747,7 @@ class ActionBase(with_metaclass(ABCMeta, object)): # only applied for the default executable to avoid interfering with the raw action cmd = self._connection._shell.append_command(cmd, 'sleep 0') if executable: - cmd = executable + ' -c ' + pipes.quote(cmd) + cmd = executable + ' -c ' + shlex_quote(cmd) display.debug("_low_level_execute_command(): executing: %s" % (cmd,)) diff --git a/lib/ansible/plugins/action/async.py b/lib/ansible/plugins/action/async.py index 6c348c7d9f..e4c67371a1 100644 --- a/lib/ansible/plugins/action/async.py +++ b/lib/ansible/plugins/action/async.py @@ -18,11 +18,11 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type import json -import pipes import random from ansible import constants as C from ansible.compat.six import iteritems +from ansible.compat.six.moves import shlex_quote from ansible.module_utils._text import to_text from ansible.plugins.action import ActionBase @@ -48,8 +48,6 @@ class ActionModule(ActionBase): module_name = self._task.action - - env_string = self._compute_environment_string() module_args = self._task.args.copy() @@ -77,7 +75,7 @@ class ActionModule(ActionBase): elif module_style == 'old': args_data = "" for k, v in iteritems(module_args): - args_data += '%s="%s" ' % (k, pipes.quote(to_text(v))) + args_data += '%s="%s" ' % (k, shlex_quote(to_text(v))) argsfile = self._transfer_data(self._connection._shell.join_path(tmp, 'arguments'), args_data) remote_paths = tmp, remote_module_path, remote_async_module_path diff --git a/lib/ansible/plugins/connection/chroot.py b/lib/ansible/plugins/connection/chroot.py index d067027a91..2c2c35341e 100644 --- a/lib/ansible/plugins/connection/chroot.py +++ b/lib/ansible/plugins/connection/chroot.py @@ -22,11 +22,11 @@ __metaclass__ = type import distutils.spawn import os import os.path -import pipes import subprocess import traceback from ansible import constants as C +from ansible.compat.six.moves import shlex_quote from ansible.errors import AnsibleError from ansible.module_utils.basic import is_executable from ansible.module_utils._text import to_bytes @@ -128,7 +128,7 @@ class Connection(ConnectionBase): super(Connection, self).put_file(in_path, out_path) display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.chroot) - out_path = pipes.quote(self._prefix_login_path(out_path)) + out_path = shlex_quote(self._prefix_login_path(out_path)) try: with open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb') as in_file: try: @@ -150,7 +150,7 @@ class Connection(ConnectionBase): super(Connection, self).fetch_file(in_path, out_path) display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.chroot) - in_path = pipes.quote(self._prefix_login_path(in_path)) + in_path = shlex_quote(self._prefix_login_path(in_path)) try: p = self._buffered_exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE)) except OSError: diff --git a/lib/ansible/plugins/connection/docker.py b/lib/ansible/plugins/connection/docker.py index f4b991ad51..8fe4d3f8a5 100644 --- a/lib/ansible/plugins/connection/docker.py +++ b/lib/ansible/plugins/connection/docker.py @@ -27,13 +27,13 @@ __metaclass__ = type import distutils.spawn import os import os.path -import pipes import subprocess import re from distutils.version import LooseVersion import ansible.constants as C +from ansible.compat.six.moves import shlex_quote from ansible.errors import AnsibleError, AnsibleFileNotFound from ansible.module_utils._text import to_bytes from ansible.plugins.connection import ConnectionBase, BUFSIZE @@ -228,7 +228,7 @@ class Connection(ConnectionBase): raise AnsibleFileNotFound( "file or module does not exist: %s" % in_path) - out_path = pipes.quote(out_path) + out_path = shlex_quote(out_path) # Older docker doesn't have native support for copying files into # running containers, so we use docker exec to implement this # Although docker version 1.8 and later provide support, the diff --git a/lib/ansible/plugins/connection/jail.py b/lib/ansible/plugins/connection/jail.py index 93936a0a78..f6bd394ad7 100644 --- a/lib/ansible/plugins/connection/jail.py +++ b/lib/ansible/plugins/connection/jail.py @@ -23,10 +23,10 @@ __metaclass__ = type import distutils.spawn import os import os.path -import pipes import subprocess import traceback +from ansible.compat.six.moves import shlex_quote from ansible.errors import AnsibleError from ansible.module_utils._text import to_bytes from ansible.plugins.connection import ConnectionBase, BUFSIZE @@ -150,7 +150,7 @@ class Connection(ConnectionBase): super(Connection, self).put_file(in_path, out_path) display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.jail) - out_path = pipes.quote(self._prefix_login_path(out_path)) + out_path = shlex_quote(self._prefix_login_path(out_path)) try: with open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb') as in_file: try: @@ -172,7 +172,7 @@ class Connection(ConnectionBase): super(Connection, self).fetch_file(in_path, out_path) display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.jail) - in_path = pipes.quote(self._prefix_login_path(in_path)) + in_path = shlex_quote(self._prefix_login_path(in_path)) try: p = self._buffered_exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE)) except OSError: diff --git a/lib/ansible/plugins/connection/libvirt_lxc.py b/lib/ansible/plugins/connection/libvirt_lxc.py index 4ccb66f556..77f377eafb 100644 --- a/lib/ansible/plugins/connection/libvirt_lxc.py +++ b/lib/ansible/plugins/connection/libvirt_lxc.py @@ -23,11 +23,11 @@ __metaclass__ = type import distutils.spawn import os import os.path -import pipes import subprocess import traceback from ansible import constants as C +from ansible.compat.six.moves import shlex_quote from ansible.errors import AnsibleError from ansible.module_utils._text import to_bytes from ansible.plugins.connection import ConnectionBase, BUFSIZE @@ -129,7 +129,7 @@ class Connection(ConnectionBase): super(Connection, self).put_file(in_path, out_path) display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.lxc) - out_path = pipes.quote(self._prefix_login_path(out_path)) + out_path = shlex_quote(self._prefix_login_path(out_path)) try: with open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb') as in_file: try: @@ -151,7 +151,7 @@ class Connection(ConnectionBase): super(Connection, self).fetch_file(in_path, out_path) display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.lxc) - in_path = pipes.quote(self._prefix_login_path(in_path)) + in_path = shlex_quote(self._prefix_login_path(in_path)) try: p = self._buffered_exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE)) except OSError: diff --git a/lib/ansible/plugins/connection/ssh.py b/lib/ansible/plugins/connection/ssh.py index cf6df55439..62d1bdedf8 100644 --- a/lib/ansible/plugins/connection/ssh.py +++ b/lib/ansible/plugins/connection/ssh.py @@ -22,7 +22,6 @@ __metaclass__ = type import errno import fcntl import os -import pipes import pty import select import subprocess @@ -30,6 +29,7 @@ import time from ansible import constants as C from ansible.compat.six import PY3, text_type, binary_type +from ansible.compat.six.moves import shlex_quote from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound from ansible.errors import AnsibleOptionsError from ansible.module_utils.basic import BOOLEANS @@ -324,7 +324,7 @@ class Connection(ConnectionBase): Starts the command and communicates with it until it ends. ''' - display_cmd = list(map(pipes.quote, map(to_text, cmd))) + display_cmd = list(map(shlex_quote, map(to_text, cmd))) display.vvv(u'SSH: EXEC {0}'.format(u' '.join(display_cmd)), host=self.host) # Start the given command. If we don't need to pipeline data, we can try @@ -626,9 +626,9 @@ class Connection(ConnectionBase): for method in methods: if method == 'sftp': cmd = self._build_command('sftp', to_bytes(host)) - in_data = u"{0} {1} {2}\n".format(sftp_action, pipes.quote(in_path), pipes.quote(out_path)) + in_data = u"{0} {1} {2}\n".format(sftp_action, shlex_quote(in_path), shlex_quote(out_path)) elif method == 'scp': - cmd = self._build_command('scp', in_path, u'{0}:{1}'.format(host, pipes.quote(out_path))) + cmd = self._build_command('scp', in_path, u'{0}:{1}'.format(host, shlex_quote(out_path))) in_data = None in_data = to_bytes(in_data, nonstring='passthru') diff --git a/lib/ansible/plugins/connection/zone.py b/lib/ansible/plugins/connection/zone.py index 3c1322d3ec..b52ad41022 100644 --- a/lib/ansible/plugins/connection/zone.py +++ b/lib/ansible/plugins/connection/zone.py @@ -24,11 +24,11 @@ __metaclass__ = type import distutils.spawn import os import os.path -import pipes import subprocess import traceback from ansible import constants as C +from ansible.compat.six.moves import shlex_quote from ansible.errors import AnsibleError from ansible.plugins.connection import ConnectionBase, BUFSIZE from ansible.module_utils._text import to_bytes @@ -149,7 +149,7 @@ class Connection(ConnectionBase): super(Connection, self).put_file(in_path, out_path) display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.zone) - out_path = pipes.quote(self._prefix_login_path(out_path)) + out_path = shlex_quote(self._prefix_login_path(out_path)) try: with open(in_path, 'rb') as in_file: try: @@ -171,7 +171,7 @@ class Connection(ConnectionBase): super(Connection, self).fetch_file(in_path, out_path) display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.zone) - in_path = pipes.quote(self._prefix_login_path(in_path)) + in_path = shlex_quote(self._prefix_login_path(in_path)) try: p = self._buffered_exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE)) except OSError: diff --git a/lib/ansible/plugins/filter/core.py b/lib/ansible/plugins/filter/core.py index bbd7b295b3..39b92a28f8 100644 --- a/lib/ansible/plugins/filter/core.py +++ b/lib/ansible/plugins/filter/core.py @@ -25,7 +25,6 @@ import itertools import json import os.path import ntpath -import pipes import glob import re import crypt @@ -48,6 +47,7 @@ except: from ansible import errors from ansible.compat.six import iteritems, string_types from ansible.compat.six.moves import reduce +from ansible.compat.six.moves import shlex_quote from ansible.module_utils._text import to_text from ansible.parsing.yaml.dumper import AnsibleDumper from ansible.utils.hashing import md5s, checksum_s @@ -123,7 +123,7 @@ def to_datetime(string, format="%Y-%d-%m %H:%M:%S"): def quote(a): ''' return its argument quoted for shell usage ''' - return pipes.quote(a) + return shlex_quote(a) def fileglob(pathname): ''' return list of matched regular files for glob ''' diff --git a/lib/ansible/plugins/shell/__init__.py b/lib/ansible/plugins/shell/__init__.py index 44af0abb74..1a88009e9e 100644 --- a/lib/ansible/plugins/shell/__init__.py +++ b/lib/ansible/plugins/shell/__init__.py @@ -19,15 +19,16 @@ __metaclass__ = type import os import re -import pipes import ansible.constants as C import time import random from ansible.compat.six import text_type +from ansible.compat.six.moves import shlex_quote _USER_HOME_PATH_RE = re.compile(r'^~[_.A-Za-z0-9][-_.A-Za-z0-9]*$') + class ShellBase(object): def __init__(self): @@ -44,7 +45,7 @@ class ShellBase(object): def env_prefix(self, **kwargs): env = self.env.copy() env.update(kwargs) - return ' '.join(['%s=%s' % (k, pipes.quote(text_type(v))) for k,v in env.items()]) + return ' '.join(['%s=%s' % (k, shlex_quote(text_type(v))) for k,v in env.items()]) def join_path(self, *args): return os.path.join(*args) @@ -60,14 +61,14 @@ class ShellBase(object): def chmod(self, paths, mode): cmd = ['chmod', mode] cmd.extend(paths) - cmd = [pipes.quote(c) for c in cmd] + cmd = [shlex_quote(c) for c in cmd] return ' '.join(cmd) def chown(self, paths, user): cmd = ['chown', user] cmd.extend(paths) - cmd = [pipes.quote(c) for c in cmd] + cmd = [shlex_quote(c) for c in cmd] return ' '.join(cmd) @@ -75,19 +76,19 @@ class ShellBase(object): """Only sets acls for users as that's really all we need""" cmd = ['setfacl', '-m', 'u:%s:%s' % (user, mode)] cmd.extend(paths) - cmd = [pipes.quote(c) for c in cmd] + cmd = [shlex_quote(c) for c in cmd] return ' '.join(cmd) def remove(self, path, recurse=False): - path = pipes.quote(path) + path = shlex_quote(path) cmd = 'rm -f ' if recurse: cmd += '-r ' return cmd + "%s %s" % (path, self._SHELL_REDIRECT_ALLNULL) def exists(self, path): - cmd = ['test', '-e', pipes.quote(path)] + cmd = ['test', '-e', shlex_quote(path)] return ' '.join(cmd) def mkdtemp(self, basefile=None, system=False, mode=None): @@ -138,14 +139,14 @@ class ShellBase(object): # Check that the user_path to expand is safe if user_home_path != '~': if not _USER_HOME_PATH_RE.match(user_home_path): - # pipes.quote will make the shell return the string verbatim - user_home_path = pipes.quote(user_home_path) + # shlex_quote will make the shell return the string verbatim + user_home_path = shlex_quote(user_home_path) return 'echo %s' % user_home_path def build_module_command(self, env_string, shebang, cmd, arg_path=None, rm_tmp=None): # don't quote the cmd if it's an empty string, because this will break pipelining mode if cmd.strip() != '': - cmd = pipes.quote(cmd) + cmd = shlex_quote(cmd) cmd_parts = [] if shebang: diff --git a/lib/ansible/plugins/shell/fish.py b/lib/ansible/plugins/shell/fish.py index ddee24ac6d..c8aa148b5c 100644 --- a/lib/ansible/plugins/shell/fish.py +++ b/lib/ansible/plugins/shell/fish.py @@ -17,9 +17,10 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type -import pipes from ansible.plugins.shell.sh import ShellModule as ShModule from ansible.compat.six import text_type +from ansible.compat.six.moves import shlex_quote + class ShellModule(ShModule): @@ -40,12 +41,12 @@ class ShellModule(ShModule): def env_prefix(self, **kwargs): env = self.env.copy() env.update(kwargs) - return ' '.join(['set -lx %s %s;' % (k, pipes.quote(text_type(v))) for k,v in env.items()]) + return ' '.join(['set -lx %s %s;' % (k, shlex_quote(text_type(v))) for k,v in env.items()]) def build_module_command(self, env_string, shebang, cmd, arg_path=None, rm_tmp=None): # don't quote the cmd if it's an empty string, because this will break pipelining mode if cmd.strip() != '': - cmd = pipes.quote(cmd) + cmd = shlex_quote(cmd) cmd_parts = [env_string.strip(), shebang.replace("#!", "").strip(), cmd] if arg_path is not None: cmd_parts.append(arg_path) @@ -82,7 +83,7 @@ class ShellModule(ShModule): # Quoting gets complex here. We're writing a python string that's # used by a variety of shells on the remote host to invoke a python # "one-liner". - shell_escaped_path = pipes.quote(path) + shell_escaped_path = shlex_quote(path) test = "set rc flag; [ -r %(p)s ] %(shell_or)s set rc 2; [ -f %(p)s ] %(shell_or)s set rc 1; [ -d %(p)s ] %(shell_and)s set rc 3; %(i)s -V 2>/dev/null %(shell_or)s set rc 4; [ x\"$rc\" != \"xflag\" ] %(shell_and)s echo \"$rc \"%(p)s %(shell_and)s exit 0" % dict(p=shell_escaped_path, i=python_interp, shell_and=self._SHELL_AND, shell_or=self._SHELL_OR) csums = [ u"({0} -c 'import hashlib; BLOCKSIZE = 65536; hasher = hashlib.sha1();{2}afile = open(\"'{1}'\", \"rb\"){2}buf = afile.read(BLOCKSIZE){2}while len(buf) > 0:{2}\thasher.update(buf){2}\tbuf = afile.read(BLOCKSIZE){2}afile.close(){2}print(hasher.hexdigest())' 2>/dev/null)".format(python_interp, shell_escaped_path, self._SHELL_EMBEDDED_PY_EOL), # Python > 2.4 (including python3) diff --git a/lib/ansible/plugins/shell/sh.py b/lib/ansible/plugins/shell/sh.py index 671eb7139e..a12c66c052 100644 --- a/lib/ansible/plugins/shell/sh.py +++ b/lib/ansible/plugins/shell/sh.py @@ -17,8 +17,8 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type -import pipes +from ansible.compat.six.moves import shlex_quote from ansible.plugins.shell import ShellBase @@ -71,7 +71,7 @@ class ShellModule(ShellBase): # Quoting gets complex here. We're writing a python string that's # used by a variety of shells on the remote host to invoke a python # "one-liner". - shell_escaped_path = pipes.quote(path) + shell_escaped_path = shlex_quote(path) test = "rc=flag; [ -r %(p)s ] %(shell_or)s rc=2; [ -f %(p)s ] %(shell_or)s rc=1; [ -d %(p)s ] %(shell_and)s rc=3; %(i)s -V 2>/dev/null %(shell_or)s rc=4; [ x\"$rc\" != \"xflag\" ] %(shell_and)s echo \"${rc} \"%(p)s %(shell_and)s exit 0" % dict(p=shell_escaped_path, i=python_interp, shell_and=self._SHELL_AND, shell_or=self._SHELL_OR) csums = [ u"({0} -c 'import hashlib; BLOCKSIZE = 65536; hasher = hashlib.sha1();{2}afile = open(\"'{1}'\", \"rb\"){2}buf = afile.read(BLOCKSIZE){2}while len(buf) > 0:{2}\thasher.update(buf){2}\tbuf = afile.read(BLOCKSIZE){2}afile.close(){2}print(hasher.hexdigest())' 2>/dev/null)".format(python_interp, shell_escaped_path, self._SHELL_EMBEDDED_PY_EOL), # Python > 2.4 (including python3) diff --git a/test/units/playbook/test_play_context.py b/test/units/playbook/test_play_context.py index a6b2094ed0..adbd54f2bb 100644 --- a/test/units/playbook/test_play_context.py +++ b/test/units/playbook/test_play_context.py @@ -20,12 +20,12 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type import os -import pipes from ansible.compat.tests import unittest from ansible.compat.tests.mock import patch, MagicMock from ansible import constants as C +from ansible.compat.six.moves import shlex_quote from ansible.cli import CLI from ansible.errors import AnsibleError, AnsibleParserError from ansible.playbook.play_context import PlayContext @@ -181,7 +181,7 @@ class TestPlayContext(unittest.TestCase): play_context.become_pass = 'testpass' play_context.become_method = 'dzdo' cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") - self.assertEqual(cmd, """%s -p %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, pipes.quote(play_context.prompt), play_context.become_user, default_exe, play_context.success_key, default_cmd)) + self.assertEqual(cmd, """%s -p %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, shlex_quote(play_context.prompt), play_context.become_user, default_exe, play_context.success_key, default_cmd)) class TestTaskAndVariableOverrride(unittest.TestCase): diff --git a/test/units/plugins/action/test_action.py b/test/units/plugins/action/test_action.py index 52083257a7..1542a2d0fc 100644 --- a/test/units/plugins/action/test_action.py +++ b/test/units/plugins/action/test_action.py @@ -20,7 +20,6 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type -import pipes import os try: @@ -32,6 +31,7 @@ from nose.tools import eq_, raises from ansible import constants as C from ansible.compat.six import text_type +from ansible.compat.six.moves import shlex_quote from ansible.compat.tests import unittest from ansible.compat.tests.mock import patch, MagicMock, mock_open @@ -164,7 +164,7 @@ class TestActionBase(unittest.TestCase): # create a mock connection, so we don't actually try and connect to things def env_prefix(**args): - return ' '.join(['%s=%s' % (k, pipes.quote(text_type(v))) for k,v in args.items()]) + return ' '.join(['%s=%s' % (k, shlex_quote(text_type(v))) for k,v in args.items()]) mock_connection = MagicMock() mock_connection._shell.env_prefix.side_effect = env_prefix diff --git a/test/units/plugins/connection/test_ssh.py b/test/units/plugins/connection/test_ssh.py index 04d456f325..73dc0685ef 100644 --- a/test/units/plugins/connection/test_ssh.py +++ b/test/units/plugins/connection/test_ssh.py @@ -21,13 +21,13 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type -import pipes from io import StringIO from ansible.compat.tests import unittest from ansible.compat.tests.mock import patch, MagicMock from ansible import constants as C +from ansible.compat.six.moves import shlex_quote from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound from ansible.playbook.play_context import PlayContext from ansible.plugins.connection import ssh @@ -311,7 +311,7 @@ class TestConnectionBaseClass(unittest.TestCase): # Test with C.DEFAULT_SCP_IF_SSH set to smart # Test when SFTP works C.DEFAULT_SCP_IF_SSH = 'smart' - expected_in_data = b' '.join((b'put', to_bytes(pipes.quote('/path/to/in/file')), to_bytes(pipes.quote('/path/to/dest/file')))) + b'\n' + expected_in_data = b' '.join((b'put', to_bytes(shlex_quote('/path/to/in/file')), to_bytes(shlex_quote('/path/to/dest/file')))) + b'\n' conn.put_file('/path/to/in/file', '/path/to/dest/file') conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False) @@ -331,13 +331,13 @@ class TestConnectionBaseClass(unittest.TestCase): # test with C.DEFAULT_SCP_IF_SSH disabled C.DEFAULT_SCP_IF_SSH = False - expected_in_data = b' '.join((b'put', to_bytes(pipes.quote('/path/to/in/file')), to_bytes(pipes.quote('/path/to/dest/file')))) + b'\n' + expected_in_data = b' '.join((b'put', to_bytes(shlex_quote('/path/to/in/file')), to_bytes(shlex_quote('/path/to/dest/file')))) + b'\n' conn.put_file('/path/to/in/file', '/path/to/dest/file') conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False) expected_in_data = b' '.join((b'put', - to_bytes(pipes.quote('/path/to/in/file/with/unicode-fö〩')), - to_bytes(pipes.quote('/path/to/dest/file/with/unicode-fö〩')))) + b'\n' + to_bytes(shlex_quote('/path/to/in/file/with/unicode-fö〩')), + to_bytes(shlex_quote('/path/to/dest/file/with/unicode-fö〩')))) + b'\n' conn.put_file(u'/path/to/in/file/with/unicode-fö〩', u'/path/to/dest/file/with/unicode-fö〩') conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False) @@ -365,7 +365,7 @@ class TestConnectionBaseClass(unittest.TestCase): # Test with C.DEFAULT_SCP_IF_SSH set to smart # Test when SFTP works C.DEFAULT_SCP_IF_SSH = 'smart' - expected_in_data = b' '.join((b'get', to_bytes(pipes.quote('/path/to/in/file')), to_bytes(pipes.quote('/path/to/dest/file')))) + b'\n' + expected_in_data = b' '.join((b'get', to_bytes(shlex_quote('/path/to/in/file')), to_bytes(shlex_quote('/path/to/dest/file')))) + b'\n' conn.fetch_file('/path/to/in/file', '/path/to/dest/file') conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False) @@ -385,13 +385,13 @@ class TestConnectionBaseClass(unittest.TestCase): # test with C.DEFAULT_SCP_IF_SSH disabled C.DEFAULT_SCP_IF_SSH = False - expected_in_data = b' '.join((b'get', to_bytes(pipes.quote('/path/to/in/file')), to_bytes(pipes.quote('/path/to/dest/file')))) + b'\n' + expected_in_data = b' '.join((b'get', to_bytes(shlex_quote('/path/to/in/file')), to_bytes(shlex_quote('/path/to/dest/file')))) + b'\n' conn.fetch_file('/path/to/in/file', '/path/to/dest/file') conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False) expected_in_data = b' '.join((b'get', - to_bytes(pipes.quote('/path/to/in/file/with/unicode-fö〩')), - to_bytes(pipes.quote('/path/to/dest/file/with/unicode-fö〩')))) + b'\n' + to_bytes(shlex_quote('/path/to/in/file/with/unicode-fö〩')), + to_bytes(shlex_quote('/path/to/dest/file/with/unicode-fö〩')))) + b'\n' conn.fetch_file(u'/path/to/in/file/with/unicode-fö〩', u'/path/to/dest/file/with/unicode-fö〩') conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False)