Make connection plugins use password from config (#69670)

Change:
Rather than connection plugins directly accessing play_context and pulling
the password from there, have them pull it from the config system, and
have TaskExecutor store it there for now.

Internally, it still routes through play_context for now, but this is
the first step away from that.

Test Plan:
- Local test with `ansible -c ssh`
- grep -R play_context.pass lib/ansible/plugins/connection/
- CI

Signed-off-by: Rick Elrod <rick@elrod.me>
This commit is contained in:
Rick Elrod 2020-05-27 09:59:55 -05:00 committed by GitHub
parent 564907d8ac
commit 8b6c02fc69
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 19 additions and 11 deletions

View file

@ -1010,6 +1010,13 @@ class TaskExecutor:
task_keys = self._task.dump_attrs()
if self._play_context.password:
# The connection password is threaded through the play_context for
# now. This is something we ultimately want to avoid, but the first
# step is to get connection plugins pulling the password through the
# config system instead of directly accessing play_context.
task_keys['password'] = self._play_context.password
# set options with 'templated vars' specific to this plugin and dependent ones
self._connection.set_options(task_keys=task_keys, var_options=options)
varnames.extend(self._set_plugin_options('shell', variables, templar, task_keys))

View file

@ -326,7 +326,7 @@ class Connection(ConnectionBase):
allow_agent = True
if self._play_context.password is not None:
if self.get_option('password') is not None:
allow_agent = False
try:
@ -344,7 +344,7 @@ class Connection(ConnectionBase):
allow_agent=allow_agent,
look_for_keys=self.get_option('look_for_keys'),
key_filename=key_filename,
password=self._play_context.password,
password=self.get_option('password'),
timeout=self._play_context.timeout,
port=port,
**ssh_connect_kwargs

View file

@ -39,6 +39,7 @@ options:
- name: ansible_password
- name: ansible_winrm_pass
- name: ansible_winrm_password
aliases: [ password ]
port:
description:
- The port for PSRP to connect on the remote target.

View file

@ -399,7 +399,7 @@ def _ssh_retry(func):
cmd_summary = u"%s..." % to_text(args[0])
for attempt in range(remaining_tries):
cmd = args[0]
if attempt != 0 and self._play_context.password and isinstance(cmd, list):
if attempt != 0 and self.get_option('password') and isinstance(cmd, list):
# If this is a retry, the fd/pipe for sshpass is closed, and we need a new one
self.sshpass_pipe = os.pipe()
cmd[1] = b'-d' + to_bytes(self.sshpass_pipe[0], nonstring='simplerepr', errors='surrogate_or_strict')
@ -417,7 +417,7 @@ def _ssh_retry(func):
except (AnsibleControlPersistBrokenPipeError):
# Retry one more time because of the ControlPersist broken pipe (see #16731)
cmd = args[0]
if self._play_context.password and isinstance(cmd, list):
if self.get_option('password') and isinstance(cmd, list):
# This is a retry, so the fd/pipe for sshpass is closed, and we need a new one
self.sshpass_pipe = os.pipe()
cmd[1] = b'-d' + to_bytes(self.sshpass_pipe[0], nonstring='simplerepr', errors='surrogate_or_strict')
@ -572,7 +572,7 @@ class Connection(ConnectionBase):
# If we want to use password authentication, we have to set up a pipe to
# write the password to sshpass.
if self._play_context.password:
if self.get_option('password'):
if not self._sshpass_available():
raise AnsibleError("to use the 'ssh' connection type with passwords, you must install the sshpass program")
@ -597,7 +597,7 @@ class Connection(ConnectionBase):
# sftp batch mode does not prompt for passwords so it must be disabled
# if not using controlpersist and using sshpass
if binary == 'sftp' and C.DEFAULT_SFTP_BATCH_MODE:
if self._play_context.password:
if self.get_option('password'):
b_args = [b'-o', b'BatchMode=no']
self._add_args(b_command, b_args, u'disable batch mode for sshpass')
b_command += [b'-b', b'-']
@ -631,7 +631,7 @@ class Connection(ConnectionBase):
b_args = (b"-o", b'IdentityFile="' + to_bytes(os.path.expanduser(key), errors='surrogate_or_strict') + b'"')
self._add_args(b_command, b_args, u"ANSIBLE_PRIVATE_KEY_FILE/private_key_file/ansible_ssh_private_key_file set")
if not self._play_context.password:
if not self.get_option('password'):
self._add_args(
b_command, (
b"-o", b"KbdInteractiveAuthentication=no",
@ -803,7 +803,7 @@ class Connection(ConnectionBase):
try:
# Make sure stdin is a proper pty to avoid tcgetattr errors
master, slave = pty.openpty()
if PY3 and self._play_context.password:
if PY3 and self.get_option('password'):
# pylint: disable=unexpected-keyword-arg
p = subprocess.Popen(cmd, stdin=slave, stdout=subprocess.PIPE, stderr=subprocess.PIPE, pass_fds=self.sshpass_pipe)
else:
@ -814,7 +814,7 @@ class Connection(ConnectionBase):
p = None
if not p:
if PY3 and self._play_context.password:
if PY3 and self.get_option('password'):
# pylint: disable=unexpected-keyword-arg
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, pass_fds=self.sshpass_pipe)
else:
@ -824,10 +824,10 @@ class Connection(ConnectionBase):
# If we are using SSH password authentication, write the password into
# the pipe we opened in _build_command.
if self._play_context.password:
if self.get_option('password'):
os.close(self.sshpass_pipe[0])
try:
os.write(self.sshpass_pipe[1], to_bytes(self._play_context.password) + b'\n')
os.write(self.sshpass_pipe[1], to_bytes(self.get_option('password')) + b'\n')
except OSError as e:
# Ignore broken pipe errors if the sshpass process has exited.
if e.errno != errno.EPIPE or p.poll() is None: