Add ansible_ssh_user/pass to enable inventory-defined users

parent c83e428a
...@@ -30,6 +30,7 @@ Ansible Changes By Release ...@@ -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
......
...@@ -374,7 +374,6 @@ class Runner(object): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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
......
...@@ -31,10 +31,10 @@ class Connection(object): ...@@ -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()
......
...@@ -34,7 +34,7 @@ except ImportError: ...@@ -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
......
...@@ -29,7 +29,7 @@ from ansible.callbacks import vvv ...@@ -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
......
...@@ -43,18 +43,18 @@ SFTP_CONNECTION_CACHE = {} ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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:
......
...@@ -31,15 +31,17 @@ from ansible import utils ...@@ -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): ...@@ -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): ...@@ -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'):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment