@ -73,6 +73,22 @@ class Connection(ConnectionBase):
''' used to identify this connection object from other classes '''
return ' ssh '
def _split_args ( self , argstring ) :
"""
Takes a string like ' -o Foo=1 -o Bar= " foo bar " ' and returns a
list [ ' -o ' , ' Foo=1 ' , ' -o ' , ' Bar=foo bar ' ] that can be added to
the argument list . The list will not contain any empty elements .
"""
return [ x . strip ( ) for x in shlex . split ( argstring ) if x . strip ( ) ]
def add_args ( self , explanation , args ) :
"""
Adds the given args to _common_args and displays a
caller - supplied explanation of why they were added .
"""
self . _common_args + = args
self . _display . vvvvv ( ' SSH: ' + explanation + ' : ( %s ) ' % ' )( ' . join ( args ) , host = self . _play_context . remote_addr )
def _connect ( self ) :
''' connect to the remote host '''
@ -81,16 +97,25 @@ class Connection(ConnectionBase):
if self . _connected :
return self
ssh_args = self . ssh_args or C . ANSIBLE_SSH_ARGS
if ssh_args is not None :
# make sure there is no empty string added as this can produce weird errors
self . _common_args + = [ x . strip ( ) for x in shlex . split ( ssh_args ) if x . strip ( ) ]
# We start with ansible_ssh_args from the inventory if it's set,
# or [ssh_connection]ssh_args from ansible.cfg, or the default
# Control* settings.
if self . ssh_args :
args = self . _split_args ( self . ssh_args )
self . add_args ( " inventory set ansible_ssh_args " , args )
elif C . ANSIBLE_SSH_ARGS :
args = self . _split_args ( C . ANSIBLE_SSH_ARGS )
self . add_args ( " ansible.cfg set ssh_args " , args )
else :
self . _common_args + = (
args = (
" -o " , " ControlMaster=auto " ,
" -o " , " ControlPersist=60s " ,
" -o " , " ControlPath= \" {0} \" " . format ( C . ANSIBLE_SSH_CONTROL_PATH % dict ( directory = self . _cp_dir ) ) ,
" -o " , " ControlPersist=60s "
)
self . add_args ( " default arguments " , args )
# If any of the above have set ControlPersist but not a
# ControlPath, add one ourselves.
cp_in_use = False
cp_path_set = False
@ -101,34 +126,68 @@ class Connection(ConnectionBase):
cp_path_set = True
if cp_in_use and not cp_path_set :
self . _common_ args + = ( " -o " , " ControlPath= \" {0} \" " . format (
args = ( " -o " , " ControlPath= \" {0} \" " . format (
C . ANSIBLE_SSH_CONTROL_PATH % dict ( directory = self . _cp_dir ) )
)
self . add_args ( " found only ControlPersist; added ControlPath " , args )
if not C . HOST_KEY_CHECKING :
self . _common_args + = ( " -o " , " StrictHostKeyChecking=no " )
self . add_args (
" ANSIBLE_HOST_KEY_CHECKING/host_key_checking disabled " ,
( " -o " , " StrictHostKeyChecking=no " )
)
if self . _play_context . port is not None :
self . _common_args + = ( " -o " , " Port= {0} " . format ( self . _play_context . port ) )
if self . _play_context . private_key_file is not None :
self . _common_args + = ( " -o " , " IdentityFile= \" {0} \" " . format ( os . path . expanduser ( self . _play_context . private_key_file ) ) )
self . add_args (
" ANSIBLE_REMOTE_PORT/remote_port/ansible_ssh_port set " ,
( " -o " , " Port= {0} " . format ( self . _play_context . port ) )
)
key = self . _play_context . private_key_file
if key :
self . add_args (
" ANSIBLE_PRIVATE_KEY_FILE/private_key_file/ansible_ssh_private_key_file set " ,
( " -o " , " IdentityFile= \" {0} \" " . format ( os . path . expanduser ( key ) ) )
)
if self . _play_context . password :
self . _common_args + = ( " -o " , " GSSAPIAuthentication=no " ,
" -o " , " PubkeyAuthentication=no " )
self . add_args (
" ansible_password/ansible_ssh_pass set " , (
" -o " , " GSSAPIAuthentication=no " ,
" -o " , " PubkeyAuthentication=no "
)
)
else :
self . _common_args + = ( " -o " , " KbdInteractiveAuthentication=no " ,
" -o " , " PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey " ,
" -o " , " PasswordAuthentication=no " )
if self . _play_context . remote_user is not None and self . _play_context . remote_user != pwd . getpwuid ( os . geteuid ( ) ) [ 0 ] :
self . _common_args + = ( " -o " , " User= {0} " . format ( self . _play_context . remote_user ) )
self . _common_args + = ( " -o " , " ConnectTimeout= {0} " . format ( self . _play_context . timeout ) )
self . add_args (
" ansible_password/ansible_ssh_pass not set " , (
" -o " , " KbdInteractiveAuthentication=no " ,
" -o " , " PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey " ,
" -o " , " PasswordAuthentication=no "
)
)
user = self . _play_context . remote_user
if user and user != pwd . getpwuid ( os . geteuid ( ) ) [ 0 ] :
self . add_args (
" ANSIBLE_REMOTE_USER/remote_user/ansible_ssh_user/user/-u set " ,
( " -o " , " User= {0} " . format ( self . _play_context . remote_user ) )
)
self . add_args (
" ANSIBLE_TIMEOUT/timeout set " ,
( " -o " , " ConnectTimeout= {0} " . format ( self . _play_context . timeout ) )
)
# If any extra SSH arguments are specified in the inventory for
# this host, or specified as an override on the command line,
# add them in.
extra_args = self . _play_context . ssh_extra_args or self . ssh_extra_args
if extra_args is not None :
self . _common_args + = [ x . strip ( ) for x in shlex . split ( extra_args ) if x . strip ( ) ]
if self . _play_context . ssh_extra_args :
args = self . _split_args ( self . _play_context . ssh_extra_args )
self . add_args ( " command-line added --ssh-extra-args " , args )
elif self . ssh_extra_args :
args = self . _split_args ( self . ssh_extra_args )
self . add_args ( " inventory added ansible_ssh_extra_args " , args )
self . _connected = True