Add ansible_ssh_user/pass to enable inventory-defined users

This commit is contained in:
Daniel Hokka Zakrisson 2013-02-10 23:22:18 +01:00
parent c83e428a7e
commit a1e00c93e5
7 changed files with 33 additions and 26 deletions

View file

@ -30,6 +30,7 @@ Ansible Changes By Release
* cron module can now also manipulate cron.d files * cron module can now also manipulate cron.d files
* virtualenv module can now inherit system site packages (or not) * virtualenv module can now inherit system site packages (or not)
* able to set the environment by setting "environment:" as a dictionary on any task (go proxy support!) * able to set the environment by setting "environment:" as a dictionary on any task (go proxy support!)
* added ansible_ssh_user and ansible_ssh_pass for per-host/group username and password
1.0 "Eruption" -- Feb 1 2013 1.0 "Eruption" -- Feb 1 2013

View file

@ -374,7 +374,6 @@ class Runner(object):
module_name = utils.template(self.basedir, module_name, inject) module_name = utils.template(self.basedir, module_name, inject)
module_args = utils.template(self.basedir, module_args, inject) module_args = utils.template(self.basedir, module_args, inject)
self.remote_user = utils.template(self.basedir, self.remote_user, inject)
if module_name in utils.plugins.action_loader: if module_name in utils.plugins.action_loader:
if self.background != 0: if self.background != 0:
@ -394,6 +393,8 @@ class Runner(object):
conn = None conn = None
actual_host = inject.get('ansible_ssh_host', host) actual_host = inject.get('ansible_ssh_host', host)
actual_port = port actual_port = port
actual_user = inject.get('ansible_ssh_user', self.remote_user)
actual_pass = inject.get('ansible_ssh_pass', self.remote_pass)
if self.transport in [ 'paramiko', 'ssh' ]: if self.transport in [ 'paramiko', 'ssh' ]:
actual_port = inject.get('ansible_ssh_port', port) actual_port = inject.get('ansible_ssh_port', port)
@ -414,6 +415,8 @@ class Runner(object):
delegate_info = inject['hostvars'][delegate_to] delegate_info = inject['hostvars'][delegate_to]
actual_host = delegate_info.get('ansible_ssh_host', delegate_to) actual_host = delegate_info.get('ansible_ssh_host', delegate_to)
actual_port = delegate_info.get('ansible_ssh_port', port) actual_port = delegate_info.get('ansible_ssh_port', port)
actual_user = delegate_info.get('ansible_ssh_user', actual_user)
actual_pass = delegate_info.get('ansible_ssh_pass', actual_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]
@ -421,6 +424,9 @@ class Runner(object):
actual_host = delegate_to actual_host = delegate_to
actual_port = port actual_port = port
actual_user = utils.template(self.basedir, actual_user, inject)
actual_pass = utils.template(self.basedir, actual_pass, inject)
try: try:
if actual_port is not None: if actual_port is not None:
actual_port = int(actual_port) actual_port = int(actual_port)
@ -429,7 +435,7 @@ class Runner(object):
return ReturnData(host=host, comm_ok=False, result=result) return ReturnData(host=host, comm_ok=False, result=result)
try: try:
conn = self.connector.connect(actual_host, actual_port) conn = self.connector.connect(actual_host, actual_port, actual_user, actual_pass)
if delegate_to or host != actual_host: if delegate_to or host != actual_host:
conn.delegate = host conn.delegate = host

View file

@ -31,10 +31,10 @@ class Connection(object):
def __init__(self, runner): def __init__(self, runner):
self.runner = runner self.runner = runner
def connect(self, host, port): def connect(self, host, port, user, password):
conn = None conn = None
transport = self.runner.transport transport = self.runner.transport
conn = utils.plugins.connection_loader.get(transport, self.runner, host, port) conn = utils.plugins.connection_loader.get(transport, self.runner, host, port, user=user, password=password)
if conn is None: if conn is None:
raise AnsibleError("unsupported connection type: %s" % transport) raise AnsibleError("unsupported connection type: %s" % transport)
self.active = conn.connect() self.active = conn.connect()

View file

@ -34,7 +34,7 @@ except ImportError:
class Connection(object): class Connection(object):
''' ZeroMQ accelerated connection ''' ''' ZeroMQ accelerated connection '''
def __init__(self, runner, host, port): def __init__(self, runner, host, port, **kwargs):
self.runner = runner self.runner = runner

View file

@ -29,7 +29,7 @@ from ansible.callbacks import vvv
class Connection(object): class Connection(object):
''' Local based connections ''' ''' Local based connections '''
def __init__(self, runner, host, port): def __init__(self, runner, host, port, **kwargs):
self.runner = runner self.runner = runner
self.host = host self.host = host
# port is unused, since this is local # port is unused, since this is local

View file

@ -43,18 +43,18 @@ SFTP_CONNECTION_CACHE = {}
class Connection(object): class Connection(object):
''' SSH based connections with Paramiko ''' ''' SSH based connections with Paramiko '''
def __init__(self, runner, host, port=None): def __init__(self, runner, host, port, user, password):
self.ssh = None self.ssh = None
self.sftp = None self.sftp = None
self.runner = runner self.runner = runner
self.host = host self.host = host
self.port = port self.port = port
if port is None: self.user = user
self.port = self.runner.remote_port self.password = password
def _cache_key(self): def _cache_key(self):
return "%s__%s__" % (self.host, self.runner.remote_user) return "%s__%s__" % (self.host, self.user)
def connect(self): def connect(self):
cache_key = self._cache_key() cache_key = self._cache_key()
@ -70,23 +70,21 @@ class Connection(object):
if not HAVE_PARAMIKO: if not HAVE_PARAMIKO:
raise errors.AnsibleError("paramiko is not installed") raise errors.AnsibleError("paramiko is not installed")
user = self.runner.remote_user vvv("ESTABLISH CONNECTION FOR USER: %s on PORT %s TO %s" % (self.user, self.port, self.host), host=self.host)
vvv("ESTABLISH CONNECTION FOR USER: %s on PORT %s TO %s" % (user, self.port, self.host), host=self.host)
ssh = paramiko.SSHClient() ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
allow_agent = True allow_agent = True
if self.runner.remote_pass is not None: if self.password is not None:
allow_agent = False allow_agent = False
try: try:
if self.runner.private_key_file: if self.runner.private_key_file:
key_filename = os.path.expanduser(self.runner.private_key_file) key_filename = os.path.expanduser(self.runner.private_key_file)
else: else:
key_filename = None key_filename = None
ssh.connect(self.host, username=user, allow_agent=allow_agent, look_for_keys=True, ssh.connect(self.host, username=self.user, allow_agent=allow_agent, look_for_keys=True,
key_filename=key_filename, password=self.runner.remote_pass, key_filename=key_filename, password=self.password,
timeout=self.runner.timeout, port=self.port) timeout=self.runner.timeout, port=self.port)
except Exception, e: except Exception, e:
msg = str(e) msg = str(e)
@ -94,7 +92,7 @@ class Connection(object):
raise errors.AnsibleError("paramiko version issue, please upgrade paramiko on the machine running ansible") raise errors.AnsibleError("paramiko version issue, please upgrade paramiko on the machine running ansible")
elif "Private key file is encrypted" in msg: elif "Private key file is encrypted" in msg:
msg = 'ssh %s@%s:%s : %s\nTo connect as a different user, use -u <username>.' % ( msg = 'ssh %s@%s:%s : %s\nTo connect as a different user, use -u <username>.' % (
user, self.host, self.port, msg) self.user, self.host, self.port, msg)
raise errors.AnsibleConnectionFailed(msg) raise errors.AnsibleConnectionFailed(msg)
else: else:
raise errors.AnsibleConnectionFailed(msg) raise errors.AnsibleConnectionFailed(msg)
@ -161,7 +159,7 @@ class Connection(object):
raise errors.AnsibleError("failed to transfer file to %s" % out_path) raise errors.AnsibleError("failed to transfer file to %s" % out_path)
def _connect_sftp(self): def _connect_sftp(self):
cache_key = "%s__%s__" % (self.host, self.runner.remote_user) cache_key = "%s__%s__" % (self.host, self.user)
if cache_key in SFTP_CONNECTION_CACHE: if cache_key in SFTP_CONNECTION_CACHE:
return SFTP_CONNECTION_CACHE[cache_key] return SFTP_CONNECTION_CACHE[cache_key]
else: else:

View file

@ -31,15 +31,17 @@ from ansible import utils
class Connection(object): class Connection(object):
''' ssh based connections ''' ''' ssh based connections '''
def __init__(self, runner, host, port): def __init__(self, runner, host, port, user, password):
self.runner = runner self.runner = runner
self.host = host self.host = host
self.port = port self.port = port
self.user = user
self.password = password
def connect(self): def connect(self):
''' connect to the remote host ''' ''' connect to the remote host '''
vvv("ESTABLISH CONNECTION FOR USER: %s" % self.runner.remote_user, host=self.host) vvv("ESTABLISH CONNECTION FOR USER: %s" % self.user, host=self.host)
self.common_args = [] self.common_args = []
extra_args = C.ANSIBLE_SSH_ARGS extra_args = C.ANSIBLE_SSH_ARGS
@ -54,19 +56,19 @@ class Connection(object):
self.common_args += ["-o", "Port=%d" % (self.port)] self.common_args += ["-o", "Port=%d" % (self.port)]
if self.runner.private_key_file is not None: if self.runner.private_key_file is not None:
self.common_args += ["-o", "IdentityFile="+os.path.expanduser(self.runner.private_key_file)] self.common_args += ["-o", "IdentityFile="+os.path.expanduser(self.runner.private_key_file)]
if self.runner.remote_pass: if self.password:
self.common_args += ["-o", "GSSAPIAuthentication=no", self.common_args += ["-o", "GSSAPIAuthentication=no",
"-o", "PubkeyAuthentication=no"] "-o", "PubkeyAuthentication=no"]
else: else:
self.common_args += ["-o", "KbdInteractiveAuthentication=no", self.common_args += ["-o", "KbdInteractiveAuthentication=no",
"-o", "PasswordAuthentication=no"] "-o", "PasswordAuthentication=no"]
self.common_args += ["-o", "User="+self.runner.remote_user] self.common_args += ["-o", "User="+self.user]
self.common_args += ["-o", "ConnectTimeout="+str(self.runner.timeout)] self.common_args += ["-o", "ConnectTimeout=%d" % self.runner.timeout]
return self return self
def _password_cmd(self): def _password_cmd(self):
if self.runner.remote_pass: if self.password:
try: try:
p = subprocess.Popen(["sshpass"], stdin=subprocess.PIPE, p = subprocess.Popen(["sshpass"], stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@ -78,9 +80,9 @@ class Connection(object):
return [] return []
def _send_password(self): def _send_password(self):
if self.runner.remote_pass: if self.password:
os.close(self.rfd) os.close(self.rfd)
os.write(self.wfd, "%s\n" % self.runner.remote_pass) os.write(self.wfd, "%s\n" % self.password)
os.close(self.wfd) os.close(self.wfd)
def exec_command(self, cmd, tmp_path, sudo_user,sudoable=False, executable='/bin/sh'): def exec_command(self, cmd, tmp_path, sudo_user,sudoable=False, executable='/bin/sh'):