clean args only if needed

This commit is contained in:
Brian Coca 2017-10-05 18:12:02 -04:00 committed by Brian Coca
parent ff7c349f11
commit 85f727ad4b

View file

@ -781,6 +781,7 @@ class AnsibleModule(object):
self.run_command_environ_update = {} self.run_command_environ_update = {}
self._warnings = [] self._warnings = []
self._deprecations = [] self._deprecations = []
self._clean = {}
self.aliases = {} self.aliases = {}
self._legal_inputs = ['_ansible_check_mode', '_ansible_no_log', '_ansible_debug', '_ansible_diff', '_ansible_verbosity', self._legal_inputs = ['_ansible_check_mode', '_ansible_no_log', '_ansible_debug', '_ansible_diff', '_ansible_verbosity',
@ -2538,6 +2539,41 @@ class AnsibleModule(object):
return data return data
def _clean_args(self, args):
if not self._clean:
# create a printable version of the command for use in reporting later,
# which strips out things like passwords from the args list
to_clean_args = args
if PY2:
if isinstance(args, text_type):
to_clean_args = to_bytes(args)
else:
if isinstance(args, binary_type):
to_clean_args = to_text(args)
if isinstance(args, (text_type, binary_type)):
to_clean_args = shlex.split(to_clean_args)
clean_args = []
is_passwd = False
for arg in (to_native(a) for a in to_clean_args):
if is_passwd:
is_passwd = False
clean_args.append('********')
continue
if PASSWD_ARG_RE.match(arg):
sep_idx = arg.find('=')
if sep_idx > -1:
clean_args.append('%s=********' % arg[:sep_idx])
continue
else:
is_passwd = True
arg = heuristic_log_sanitize(arg, self.no_log_values)
clean_args.append(arg)
self._clean = ' '.join(shlex_quote(arg) for arg in clean_args)
return self._clean
def run_command(self, args, check_rc=False, close_fds=True, executable=None, data=None, binary_data=False, path_prefix=None, cwd=None, def run_command(self, args, check_rc=False, close_fds=True, executable=None, data=None, binary_data=False, path_prefix=None, cwd=None,
use_unsafe_shell=False, prompt_regex=None, environ_update=None, umask=None, encoding='utf-8', errors='surrogate_or_strict'): use_unsafe_shell=False, prompt_regex=None, environ_update=None, umask=None, encoding='utf-8', errors='surrogate_or_strict'):
''' '''
@ -2583,6 +2619,8 @@ class AnsibleModule(object):
according to the encoding and errors parameters. If you want byte according to the encoding and errors parameters. If you want byte
strings on python3, use encoding=None to turn decoding to text off. strings on python3, use encoding=None to turn decoding to text off.
''' '''
# used by clean args later on
self._clean = None
if not isinstance(args, (list, binary_type, text_type)): if not isinstance(args, (list, binary_type, text_type)):
msg = "Argument 'args' to run_command must be list or string" msg = "Argument 'args' to run_command must be list or string"
@ -2661,37 +2699,6 @@ class AnsibleModule(object):
if not os.environ['PYTHONPATH']: if not os.environ['PYTHONPATH']:
del os.environ['PYTHONPATH'] del os.environ['PYTHONPATH']
# create a printable version of the command for use
# in reporting later, which strips out things like
# passwords from the args list
to_clean_args = args
if PY2:
if isinstance(args, text_type):
to_clean_args = to_bytes(args)
else:
if isinstance(args, binary_type):
to_clean_args = to_text(args)
if isinstance(args, (text_type, binary_type)):
to_clean_args = shlex.split(to_clean_args)
clean_args = []
is_passwd = False
for arg in (to_native(a) for a in to_clean_args):
if is_passwd:
is_passwd = False
clean_args.append('********')
continue
if PASSWD_ARG_RE.match(arg):
sep_idx = arg.find('=')
if sep_idx > -1:
clean_args.append('%s=********' % arg[:sep_idx])
continue
else:
is_passwd = True
arg = heuristic_log_sanitize(arg, self.no_log_values)
clean_args.append(arg)
clean_args = ' '.join(shlex_quote(arg) for arg in clean_args)
if data: if data:
st_in = subprocess.PIPE st_in = subprocess.PIPE
@ -2723,7 +2730,7 @@ class AnsibleModule(object):
try: try:
if self._debug: if self._debug:
self.log('Executing: ' + clean_args) self.log('Executing: ' + self._clean_args(args))
cmd = subprocess.Popen(args, **kwargs) cmd = subprocess.Popen(args, **kwargs)
# the communication logic here is essentially taken from that # the communication logic here is essentially taken from that
@ -2772,11 +2779,11 @@ class AnsibleModule(object):
rc = cmd.returncode rc = cmd.returncode
except (OSError, IOError) as e: except (OSError, IOError) as e:
self.log("Error Executing CMD:%s Exception:%s" % (clean_args, to_native(e))) self.log("Error Executing CMD:%s Exception:%s" % (self._clean_args(args), to_native(e)))
self.fail_json(rc=e.errno, msg=to_native(e), cmd=clean_args) self.fail_json(rc=e.errno, msg=to_native(e), cmd=self._clean_args(args))
except Exception as e: except Exception as e:
self.log("Error Executing CMD:%s Exception:%s" % (clean_args, to_native(traceback.format_exc()))) self.log("Error Executing CMD:%s Exception:%s" % (self._clean_args(args), to_native(traceback.format_exc())))
self.fail_json(rc=257, msg=to_native(e), exception=traceback.format_exc(), cmd=clean_args) self.fail_json(rc=257, msg=to_native(e), exception=traceback.format_exc(), cmd=self._clean_args(args))
# Restore env settings # Restore env settings
for key, val in old_env_vals.items(): for key, val in old_env_vals.items():
@ -2790,7 +2797,7 @@ class AnsibleModule(object):
if rc != 0 and check_rc: if rc != 0 and check_rc:
msg = heuristic_log_sanitize(stderr.rstrip(), self.no_log_values) msg = heuristic_log_sanitize(stderr.rstrip(), self.no_log_values)
self.fail_json(cmd=clean_args, rc=rc, stdout=stdout, stderr=stderr, msg=msg) self.fail_json(cmd=self._clean_args(args), rc=rc, stdout=stdout, stderr=stderr, msg=msg)
# reset the pwd # reset the pwd
os.chdir(prev_dir) os.chdir(prev_dir)
@ -2798,6 +2805,7 @@ class AnsibleModule(object):
if encoding is not None: if encoding is not None:
return (rc, to_native(stdout, encoding=encoding, errors=errors), return (rc, to_native(stdout, encoding=encoding, errors=errors),
to_native(stderr, encoding=encoding, errors=errors)) to_native(stderr, encoding=encoding, errors=errors))
return (rc, stdout, stderr) return (rc, stdout, stderr)
def append_to_file(self, filename, str): def append_to_file(self, filename, str):