mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-06-30 04:00:21 -07:00
Add ansible_sudo_pass hostvar support
This commit is contained in:
parent
d154bf8781
commit
ea2ec6237a
7 changed files with 20 additions and 12 deletions
|
@ -190,6 +190,8 @@ mentioned::
|
||||||
The default ssh user name to use.
|
The default ssh user name to use.
|
||||||
ansible_ssh_pass
|
ansible_ssh_pass
|
||||||
The ssh password to use (this is insecure, we strongly recommend using --ask-pass or SSH keys)
|
The ssh password to use (this is insecure, we strongly recommend using --ask-pass or SSH keys)
|
||||||
|
ansible_sudo_pass
|
||||||
|
The sudo password to use (this is insecure, we strongly recommend using --ask-pass or SSH keys)
|
||||||
ansible_connection
|
ansible_connection
|
||||||
Connection type of the host. Candidates are local, ssh or paramiko. The default is paramiko before Ansible 1.2, and 'smart' afterwards which detects whether usage of 'ssh' would be feasible based on whether ControlPersist is supported.
|
Connection type of the host. Candidates are local, ssh or paramiko. The default is paramiko before Ansible 1.2, and 'smart' afterwards which detects whether usage of 'ssh' would be feasible based on whether ControlPersist is supported.
|
||||||
ansible_ssh_private_key_file
|
ansible_ssh_private_key_file
|
||||||
|
|
|
@ -577,6 +577,7 @@ class Runner(object):
|
||||||
actual_pass = inject.get('ansible_ssh_pass', self.remote_pass)
|
actual_pass = inject.get('ansible_ssh_pass', self.remote_pass)
|
||||||
actual_transport = inject.get('ansible_connection', self.transport)
|
actual_transport = inject.get('ansible_connection', self.transport)
|
||||||
actual_private_key_file = inject.get('ansible_ssh_private_key_file', self.private_key_file)
|
actual_private_key_file = inject.get('ansible_ssh_private_key_file', self.private_key_file)
|
||||||
|
self.sudo_pass = inject.get('ansible_sudo_pass', self.sudo_pass)
|
||||||
|
|
||||||
if self.accelerate and actual_transport != 'local':
|
if self.accelerate and actual_transport != 'local':
|
||||||
#Fix to get the inventory name of the host to accelerate plugin
|
#Fix to get the inventory name of the host to accelerate plugin
|
||||||
|
@ -616,6 +617,7 @@ class Runner(object):
|
||||||
actual_pass = delegate_info.get('ansible_ssh_pass', actual_pass)
|
actual_pass = delegate_info.get('ansible_ssh_pass', actual_pass)
|
||||||
actual_private_key_file = delegate_info.get('ansible_ssh_private_key_file', self.private_key_file)
|
actual_private_key_file = delegate_info.get('ansible_ssh_private_key_file', self.private_key_file)
|
||||||
actual_transport = delegate_info.get('ansible_connection', self.transport)
|
actual_transport = delegate_info.get('ansible_connection', self.transport)
|
||||||
|
self.sudo_pass = delegate_info.get('ansible_sudo_pass', self.sudo_pass)
|
||||||
for i in delegate_info:
|
for i in delegate_info:
|
||||||
if i.startswith("ansible_") and i.endswith("_interpreter"):
|
if i.startswith("ansible_") and i.endswith("_interpreter"):
|
||||||
inject[i] = delegate_info[i]
|
inject[i] = delegate_info[i]
|
||||||
|
|
|
@ -165,7 +165,7 @@ class Connection(object):
|
||||||
executable = constants.DEFAULT_EXECUTABLE
|
executable = constants.DEFAULT_EXECUTABLE
|
||||||
|
|
||||||
if self.runner.sudo and sudoable and sudo_user:
|
if self.runner.sudo and sudoable and sudo_user:
|
||||||
cmd, prompt = utils.make_sudo_cmd(sudo_user, executable, cmd)
|
cmd, prompt, success_key = utils.make_sudo_cmd(sudo_user, executable, cmd)
|
||||||
|
|
||||||
vvv("EXEC COMMAND %s" % cmd)
|
vvv("EXEC COMMAND %s" % cmd)
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ class Connection(object):
|
||||||
else:
|
else:
|
||||||
local_cmd = cmd
|
local_cmd = cmd
|
||||||
else:
|
else:
|
||||||
local_cmd, prompt = utils.make_sudo_cmd(sudo_user, executable, cmd)
|
local_cmd, prompt, success_key = utils.make_sudo_cmd(sudo_user, executable, cmd)
|
||||||
|
|
||||||
vvv("EXEC %s" % (local_cmd), host=self.host)
|
vvv("EXEC %s" % (local_cmd), host=self.host)
|
||||||
p = subprocess.Popen(local_cmd, shell=isinstance(local_cmd, basestring),
|
p = subprocess.Popen(local_cmd, shell=isinstance(local_cmd, basestring),
|
||||||
|
@ -63,7 +63,7 @@ class Connection(object):
|
||||||
fcntl.fcntl(p.stderr, fcntl.F_SETFL,
|
fcntl.fcntl(p.stderr, fcntl.F_SETFL,
|
||||||
fcntl.fcntl(p.stderr, fcntl.F_GETFL) | os.O_NONBLOCK)
|
fcntl.fcntl(p.stderr, fcntl.F_GETFL) | os.O_NONBLOCK)
|
||||||
sudo_output = ''
|
sudo_output = ''
|
||||||
while not sudo_output.endswith(prompt):
|
while not sudo_output.endswith(prompt) and success_key not in sudo_output:
|
||||||
rfd, wfd, efd = select.select([p.stdout, p.stderr], [],
|
rfd, wfd, efd = select.select([p.stdout, p.stderr], [],
|
||||||
[p.stdout, p.stderr], self.runner.timeout)
|
[p.stdout, p.stderr], self.runner.timeout)
|
||||||
if p.stdout in rfd:
|
if p.stdout in rfd:
|
||||||
|
@ -77,7 +77,8 @@ class Connection(object):
|
||||||
stdout, stderr = p.communicate()
|
stdout, stderr = p.communicate()
|
||||||
raise errors.AnsibleError('sudo output closed while waiting for password prompt:\n' + sudo_output)
|
raise errors.AnsibleError('sudo output closed while waiting for password prompt:\n' + sudo_output)
|
||||||
sudo_output += chunk
|
sudo_output += chunk
|
||||||
p.stdin.write(self.runner.sudo_pass + '\n')
|
if success_key not in sudo_output:
|
||||||
|
p.stdin.write(self.runner.sudo_pass + '\n')
|
||||||
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) & ~os.O_NONBLOCK)
|
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) & ~os.O_NONBLOCK)
|
||||||
fcntl.fcntl(p.stderr, fcntl.F_SETFL, fcntl.fcntl(p.stderr, fcntl.F_GETFL) & ~os.O_NONBLOCK)
|
fcntl.fcntl(p.stderr, fcntl.F_SETFL, fcntl.fcntl(p.stderr, fcntl.F_GETFL) & ~os.O_NONBLOCK)
|
||||||
|
|
||||||
|
|
|
@ -202,13 +202,13 @@ class Connection(object):
|
||||||
chan.get_pty(term=os.getenv('TERM', 'vt100'),
|
chan.get_pty(term=os.getenv('TERM', 'vt100'),
|
||||||
width=int(os.getenv('COLUMNS', 0)),
|
width=int(os.getenv('COLUMNS', 0)),
|
||||||
height=int(os.getenv('LINES', 0)))
|
height=int(os.getenv('LINES', 0)))
|
||||||
shcmd, prompt = utils.make_sudo_cmd(sudo_user, executable, cmd)
|
shcmd, prompt, success_key = utils.make_sudo_cmd(sudo_user, executable, cmd)
|
||||||
vvv("EXEC %s" % shcmd, host=self.host)
|
vvv("EXEC %s" % shcmd, host=self.host)
|
||||||
sudo_output = ''
|
sudo_output = ''
|
||||||
try:
|
try:
|
||||||
chan.exec_command(shcmd)
|
chan.exec_command(shcmd)
|
||||||
if self.runner.sudo_pass:
|
if self.runner.sudo_pass:
|
||||||
while not sudo_output.endswith(prompt):
|
while not sudo_output.endswith(prompt) and success_key not in sudo_output:
|
||||||
chunk = chan.recv(bufsize)
|
chunk = chan.recv(bufsize)
|
||||||
if not chunk:
|
if not chunk:
|
||||||
if 'unknown user' in sudo_output:
|
if 'unknown user' in sudo_output:
|
||||||
|
@ -218,7 +218,8 @@ class Connection(object):
|
||||||
raise errors.AnsibleError('ssh connection ' +
|
raise errors.AnsibleError('ssh connection ' +
|
||||||
'closed waiting for password prompt')
|
'closed waiting for password prompt')
|
||||||
sudo_output += chunk
|
sudo_output += chunk
|
||||||
chan.sendall(self.runner.sudo_pass + '\n')
|
if success_key not in sudo_output:
|
||||||
|
chan.sendall(self.runner.sudo_pass + '\n')
|
||||||
except socket.timeout:
|
except socket.timeout:
|
||||||
raise errors.AnsibleError('ssh timed out waiting for sudo.\n' + sudo_output)
|
raise errors.AnsibleError('ssh timed out waiting for sudo.\n' + sudo_output)
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,7 @@ class Connection(object):
|
||||||
else:
|
else:
|
||||||
ssh_cmd.append(cmd)
|
ssh_cmd.append(cmd)
|
||||||
else:
|
else:
|
||||||
sudocmd, prompt = utils.make_sudo_cmd(sudo_user, executable, cmd)
|
sudocmd, prompt, success_key = utils.make_sudo_cmd(sudo_user, executable, cmd)
|
||||||
ssh_cmd.append(sudocmd)
|
ssh_cmd.append(sudocmd)
|
||||||
|
|
||||||
vvv("EXEC %s" % ssh_cmd, host=self.host)
|
vvv("EXEC %s" % ssh_cmd, host=self.host)
|
||||||
|
@ -198,7 +198,7 @@ class Connection(object):
|
||||||
fcntl.fcntl(p.stdout, fcntl.F_SETFL,
|
fcntl.fcntl(p.stdout, fcntl.F_SETFL,
|
||||||
fcntl.fcntl(p.stdout, fcntl.F_GETFL) | os.O_NONBLOCK)
|
fcntl.fcntl(p.stdout, fcntl.F_GETFL) | os.O_NONBLOCK)
|
||||||
sudo_output = ''
|
sudo_output = ''
|
||||||
while not sudo_output.endswith(prompt):
|
while not sudo_output.endswith(prompt) and success_key not in sudo_output:
|
||||||
rfd, wfd, efd = select.select([p.stdout], [],
|
rfd, wfd, efd = select.select([p.stdout], [],
|
||||||
[p.stdout], self.runner.timeout)
|
[p.stdout], self.runner.timeout)
|
||||||
if p.stdout in rfd:
|
if p.stdout in rfd:
|
||||||
|
@ -209,7 +209,8 @@ class Connection(object):
|
||||||
else:
|
else:
|
||||||
stdout = p.communicate()
|
stdout = p.communicate()
|
||||||
raise errors.AnsibleError('ssh connection error waiting for sudo password prompt')
|
raise errors.AnsibleError('ssh connection error waiting for sudo password prompt')
|
||||||
stdin.write(self.runner.sudo_pass + '\n')
|
if success_key not in sudo_output:
|
||||||
|
stdin.write(self.runner.sudo_pass + '\n')
|
||||||
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) & ~os.O_NONBLOCK)
|
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) & ~os.O_NONBLOCK)
|
||||||
|
|
||||||
# We can't use p.communicate here because the ControlMaster may have stdout open as well
|
# We can't use p.communicate here because the ControlMaster may have stdout open as well
|
||||||
|
|
|
@ -844,10 +844,11 @@ def make_sudo_cmd(sudo_user, executable, cmd):
|
||||||
# the -p option.
|
# the -p option.
|
||||||
randbits = ''.join(chr(random.randint(ord('a'), ord('z'))) for x in xrange(32))
|
randbits = ''.join(chr(random.randint(ord('a'), ord('z'))) for x in xrange(32))
|
||||||
prompt = '[sudo via ansible, key=%s] password: ' % randbits
|
prompt = '[sudo via ansible, key=%s] password: ' % randbits
|
||||||
|
success_key = 'SUDO-SUCCESS-%s' % randbits
|
||||||
sudocmd = '%s -k && %s %s -S -p "%s" -u %s %s -c %s' % (
|
sudocmd = '%s -k && %s %s -S -p "%s" -u %s %s -c %s' % (
|
||||||
C.DEFAULT_SUDO_EXE, C.DEFAULT_SUDO_EXE, C.DEFAULT_SUDO_FLAGS,
|
C.DEFAULT_SUDO_EXE, C.DEFAULT_SUDO_EXE, C.DEFAULT_SUDO_FLAGS,
|
||||||
prompt, sudo_user, executable or '$SHELL', pipes.quote(cmd))
|
prompt, sudo_user, executable or '$SHELL', pipes.quote('echo %s; %s' % (success_key, cmd)))
|
||||||
return ('/bin/sh -c ' + pipes.quote(sudocmd), prompt)
|
return ('/bin/sh -c ' + pipes.quote(sudocmd), prompt, success_key)
|
||||||
|
|
||||||
_TO_UNICODE_TYPES = (unicode, type(None))
|
_TO_UNICODE_TYPES = (unicode, type(None))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue