Winrm fixes for devel
* Include fixes for winrm connection plugin from v1 code * Fixing shell plugin use
This commit is contained in:
parent
2a8ab4ab3e
commit
2a5fbd8570
4 changed files with 40 additions and 30 deletions
|
@ -31,7 +31,6 @@ from ansible import constants as C
|
||||||
from ansible.errors import AnsibleError
|
from ansible.errors import AnsibleError
|
||||||
from ansible.executor.module_common import modify_module
|
from ansible.executor.module_common import modify_module
|
||||||
from ansible.parsing.utils.jsonify import jsonify
|
from ansible.parsing.utils.jsonify import jsonify
|
||||||
from ansible.plugins import shell_loader
|
|
||||||
|
|
||||||
from ansible.utils.debug import debug
|
from ansible.utils.debug import debug
|
||||||
from ansible.utils.unicode import to_bytes
|
from ansible.utils.unicode import to_bytes
|
||||||
|
@ -53,18 +52,6 @@ class ActionBase:
|
||||||
self._templar = templar
|
self._templar = templar
|
||||||
self._shared_loader_obj = shared_loader_obj
|
self._shared_loader_obj = shared_loader_obj
|
||||||
|
|
||||||
# load the shell plugin for this action/connection
|
|
||||||
if self._connection_info.shell:
|
|
||||||
shell_type = self._connection_info.shell
|
|
||||||
elif hasattr(connection, '_shell'):
|
|
||||||
shell_type = getattr(connection, '_shell')
|
|
||||||
else:
|
|
||||||
shell_type = os.path.basename(C.DEFAULT_EXECUTABLE)
|
|
||||||
|
|
||||||
self._shell = shell_loader.get(shell_type)
|
|
||||||
if not self._shell:
|
|
||||||
raise AnsibleError("Invalid shell type specified (%s), or the plugin for that shell type is missing." % shell_type)
|
|
||||||
|
|
||||||
self._supports_check_mode = True
|
self._supports_check_mode = True
|
||||||
|
|
||||||
def _configure_module(self, module_name, module_args, task_vars=dict()):
|
def _configure_module(self, module_name, module_args, task_vars=dict()):
|
||||||
|
@ -104,7 +91,7 @@ class ActionBase:
|
||||||
# if type(enviro) != dict:
|
# if type(enviro) != dict:
|
||||||
# raise errors.AnsibleError("environment must be a dictionary, received %s" % enviro)
|
# raise errors.AnsibleError("environment must be a dictionary, received %s" % enviro)
|
||||||
|
|
||||||
return self._shell.env_prefix(**enviro)
|
return self._connection._shell.env_prefix(**enviro)
|
||||||
|
|
||||||
def _early_needs_tmp_path(self):
|
def _early_needs_tmp_path(self):
|
||||||
'''
|
'''
|
||||||
|
@ -151,7 +138,7 @@ class ActionBase:
|
||||||
if self._connection_info.remote_user != 'root' or self._connection_info.become and self._connection_info.become_user != 'root':
|
if self._connection_info.remote_user != 'root' or self._connection_info.become and self._connection_info.become_user != 'root':
|
||||||
tmp_mode = 'a+rx'
|
tmp_mode = 'a+rx'
|
||||||
|
|
||||||
cmd = self._shell.mkdtemp(basefile, use_system_tmp, tmp_mode)
|
cmd = self._connection._shell.mkdtemp(basefile, use_system_tmp, tmp_mode)
|
||||||
debug("executing _low_level_execute_command to create the tmp path")
|
debug("executing _low_level_execute_command to create the tmp path")
|
||||||
result = self._low_level_execute_command(cmd, None, sudoable=False)
|
result = self._low_level_execute_command(cmd, None, sudoable=False)
|
||||||
debug("done with creation of tmp path")
|
debug("done with creation of tmp path")
|
||||||
|
@ -176,8 +163,8 @@ class ActionBase:
|
||||||
raise AnsibleError(output)
|
raise AnsibleError(output)
|
||||||
|
|
||||||
# FIXME: do we still need to do this?
|
# FIXME: do we still need to do this?
|
||||||
#rc = self._shell.join_path(utils.last_non_blank_line(result['stdout']).strip(), '')
|
#rc = self._connection._shell.join_path(utils.last_non_blank_line(result['stdout']).strip(), '')
|
||||||
rc = self._shell.join_path(result['stdout'].strip(), '').splitlines()[-1]
|
rc = self._connection._shell.join_path(result['stdout'].strip(), '').splitlines()[-1]
|
||||||
|
|
||||||
# Catch failure conditions, files should never be
|
# Catch failure conditions, files should never be
|
||||||
# written to locations in /.
|
# written to locations in /.
|
||||||
|
@ -190,7 +177,7 @@ class ActionBase:
|
||||||
'''Remove a temporary path we created. '''
|
'''Remove a temporary path we created. '''
|
||||||
|
|
||||||
if tmp_path and "-tmp-" in tmp_path:
|
if tmp_path and "-tmp-" in tmp_path:
|
||||||
cmd = self._shell.remove(tmp_path, recurse=True)
|
cmd = self._connection._shell.remove(tmp_path, recurse=True)
|
||||||
# If we have gotten here we have a working ssh configuration.
|
# If we have gotten here we have a working ssh configuration.
|
||||||
# If ssh breaks we could leave tmp directories out on the remote system.
|
# If ssh breaks we could leave tmp directories out on the remote system.
|
||||||
debug("calling _low_level_execute_command to remove the tmp path")
|
debug("calling _low_level_execute_command to remove the tmp path")
|
||||||
|
@ -229,7 +216,7 @@ class ActionBase:
|
||||||
Issue a remote chmod command
|
Issue a remote chmod command
|
||||||
'''
|
'''
|
||||||
|
|
||||||
cmd = self._shell.chmod(mode, path)
|
cmd = self._connection._shell.chmod(mode, path)
|
||||||
debug("calling _low_level_execute_command to chmod the remote path")
|
debug("calling _low_level_execute_command to chmod the remote path")
|
||||||
res = self._low_level_execute_command(cmd, tmp, sudoable=sudoable)
|
res = self._low_level_execute_command(cmd, tmp, sudoable=sudoable)
|
||||||
debug("done with chmod call")
|
debug("done with chmod call")
|
||||||
|
@ -244,7 +231,7 @@ class ActionBase:
|
||||||
# variable manager data
|
# variable manager data
|
||||||
#python_interp = inject['hostvars'][inject['inventory_hostname']].get('ansible_python_interpreter', 'python')
|
#python_interp = inject['hostvars'][inject['inventory_hostname']].get('ansible_python_interpreter', 'python')
|
||||||
python_interp = 'python'
|
python_interp = 'python'
|
||||||
cmd = self._shell.checksum(path, python_interp)
|
cmd = self._connection._shell.checksum(path, python_interp)
|
||||||
debug("calling _low_level_execute_command to get the remote checksum")
|
debug("calling _low_level_execute_command to get the remote checksum")
|
||||||
data = self._low_level_execute_command(cmd, tmp, sudoable=True)
|
data = self._low_level_execute_command(cmd, tmp, sudoable=True)
|
||||||
debug("done getting the remote checksum")
|
debug("done getting the remote checksum")
|
||||||
|
@ -280,7 +267,7 @@ class ActionBase:
|
||||||
if self._connection_info.become and self._connection_info.become_user:
|
if self._connection_info.become and self._connection_info.become_user:
|
||||||
expand_path = '~%s' % self._connection_info.become_user
|
expand_path = '~%s' % self._connection_info.become_user
|
||||||
|
|
||||||
cmd = self._shell.expand_user(expand_path)
|
cmd = self._connection._shell.expand_user(expand_path)
|
||||||
debug("calling _low_level_execute_command to expand the remote user path")
|
debug("calling _low_level_execute_command to expand the remote user path")
|
||||||
data = self._low_level_execute_command(cmd, tmp, sudoable=False)
|
data = self._low_level_execute_command(cmd, tmp, sudoable=False)
|
||||||
debug("done expanding the remote user path")
|
debug("done expanding the remote user path")
|
||||||
|
@ -293,7 +280,7 @@ class ActionBase:
|
||||||
return path
|
return path
|
||||||
|
|
||||||
if len(split_path) > 1:
|
if len(split_path) > 1:
|
||||||
return self._shell.join_path(initial_fragment, *split_path[1:])
|
return self._connection._shell.join_path(initial_fragment, *split_path[1:])
|
||||||
else:
|
else:
|
||||||
return initial_fragment
|
return initial_fragment
|
||||||
|
|
||||||
|
@ -346,7 +333,7 @@ class ActionBase:
|
||||||
remote_module_path = None
|
remote_module_path = None
|
||||||
if not tmp and self._late_needs_tmp_path(tmp, module_style):
|
if not tmp and self._late_needs_tmp_path(tmp, module_style):
|
||||||
tmp = self._make_tmp_path()
|
tmp = self._make_tmp_path()
|
||||||
remote_module_path = self._shell.join_path(tmp, module_name)
|
remote_module_path = self._connection._shell.join_path(tmp, module_name)
|
||||||
|
|
||||||
# FIXME: async stuff here?
|
# FIXME: async stuff here?
|
||||||
#if (module_style != 'new' or async_jid is not None or not self._connection._has_pipelining or not C.ANSIBLE_SSH_PIPELINING or C.DEFAULT_KEEP_REMOTE_FILES):
|
#if (module_style != 'new' or async_jid is not None or not self._connection._has_pipelining or not C.ANSIBLE_SSH_PIPELINING or C.DEFAULT_KEEP_REMOTE_FILES):
|
||||||
|
@ -379,7 +366,7 @@ class ActionBase:
|
||||||
# not sudoing or sudoing to root, so can cleanup files in the same step
|
# not sudoing or sudoing to root, so can cleanup files in the same step
|
||||||
rm_tmp = tmp
|
rm_tmp = tmp
|
||||||
|
|
||||||
cmd = self._shell.build_module_command(environment_string, shebang, cmd, rm_tmp)
|
cmd = self._connection._shell.build_module_command(environment_string, shebang, cmd, rm_tmp)
|
||||||
cmd = cmd.strip()
|
cmd = cmd.strip()
|
||||||
|
|
||||||
sudoable = True
|
sudoable = True
|
||||||
|
@ -396,7 +383,7 @@ class ActionBase:
|
||||||
if self._connection_info.become and self._connection_info.become_user != 'root':
|
if self._connection_info.become and self._connection_info.become_user != 'root':
|
||||||
# not sudoing to root, so maybe can't delete files as that other user
|
# not sudoing to root, so maybe can't delete files as that other user
|
||||||
# have to clean up temp files as original user in a second step
|
# have to clean up temp files as original user in a second step
|
||||||
cmd2 = self._shell.remove(tmp, recurse=True)
|
cmd2 = self._connection._shell.remove(tmp, recurse=True)
|
||||||
self._low_level_execute_command(cmd2, tmp, sudoable=False)
|
self._low_level_execute_command(cmd2, tmp, sudoable=False)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -31,6 +31,7 @@ from six import with_metaclass
|
||||||
|
|
||||||
from ansible import constants as C
|
from ansible import constants as C
|
||||||
from ansible.errors import AnsibleError
|
from ansible.errors import AnsibleError
|
||||||
|
from ansible.plugins import shell_loader
|
||||||
|
|
||||||
# FIXME: this object should be created upfront and passed through
|
# FIXME: this object should be created upfront and passed through
|
||||||
# the entire chain of calls to here, as there are other things
|
# the entire chain of calls to here, as there are other things
|
||||||
|
@ -71,6 +72,18 @@ class ConnectionBase(with_metaclass(ABCMeta, object)):
|
||||||
self.success_key = None
|
self.success_key = None
|
||||||
self.prompt = None
|
self.prompt = None
|
||||||
|
|
||||||
|
# load the shell plugin for this action/connection
|
||||||
|
if connection_info.shell:
|
||||||
|
shell_type = connection_info.shell
|
||||||
|
elif hasattr(self, '_shell_type'):
|
||||||
|
shell_type = getattr(self, '_shell_type')
|
||||||
|
else:
|
||||||
|
shell_type = os.path.basename(C.DEFAULT_EXECUTABLE)
|
||||||
|
|
||||||
|
self._shell = shell_loader.get(shell_type)
|
||||||
|
if not self._shell:
|
||||||
|
raise AnsibleError("Invalid shell type specified (%s), or the plugin for that shell type is missing." % shell_type)
|
||||||
|
|
||||||
def _become_method_supported(self):
|
def _become_method_supported(self):
|
||||||
''' Checks if the current class supports this privilege escalation method '''
|
''' Checks if the current class supports this privilege escalation method '''
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,6 @@ from ansible.plugins import shell_loader
|
||||||
from ansible.utils.path import makedirs_safe
|
from ansible.utils.path import makedirs_safe
|
||||||
from ansible.utils.unicode import to_bytes
|
from ansible.utils.unicode import to_bytes
|
||||||
|
|
||||||
|
|
||||||
class Connection(ConnectionBase):
|
class Connection(ConnectionBase):
|
||||||
'''WinRM connections over HTTP/HTTPS.'''
|
'''WinRM connections over HTTP/HTTPS.'''
|
||||||
|
|
||||||
|
@ -63,8 +62,7 @@ class Connection(ConnectionBase):
|
||||||
self.protocol = None
|
self.protocol = None
|
||||||
self.shell_id = None
|
self.shell_id = None
|
||||||
self.delegate = None
|
self.delegate = None
|
||||||
|
self._shell_type = 'powershell'
|
||||||
self._shell = shell_loader.get('powershell')
|
|
||||||
|
|
||||||
# TODO: Add runas support
|
# TODO: Add runas support
|
||||||
self.become_methods_supported=[]
|
self.become_methods_supported=[]
|
||||||
|
|
|
@ -59,12 +59,24 @@ class ShellModule(object):
|
||||||
# FIXME: Support system temp path!
|
# FIXME: Support system temp path!
|
||||||
return self._encode_script('''(New-Item -Type Directory -Path $env:temp -Name "%s").FullName | Write-Host -Separator '';''' % basefile)
|
return self._encode_script('''(New-Item -Type Directory -Path $env:temp -Name "%s").FullName | Write-Host -Separator '';''' % basefile)
|
||||||
|
|
||||||
def md5(self, path):
|
def expand_user(self, user_home_path):
|
||||||
|
# PowerShell only supports "~" (not "~username"). Resolve-Path ~ does
|
||||||
|
# not seem to work remotely, though by default we are always starting
|
||||||
|
# in the user's home directory.
|
||||||
|
if user_home_path == '~':
|
||||||
|
script = 'Write-Host (Get-Location).Path'
|
||||||
|
elif user_home_path.startswith('~\\'):
|
||||||
|
script = 'Write-Host ((Get-Location).Path + "%s")' % _escape(user_home_path[1:])
|
||||||
|
else:
|
||||||
|
script = 'Write-Host "%s"' % _escape(user_home_path)
|
||||||
|
return self._encode_script(script)
|
||||||
|
|
||||||
|
def checksum(self, path, *args, **kwargs):
|
||||||
path = self._escape(path)
|
path = self._escape(path)
|
||||||
script = '''
|
script = '''
|
||||||
If (Test-Path -PathType Leaf "%(path)s")
|
If (Test-Path -PathType Leaf "%(path)s")
|
||||||
{
|
{
|
||||||
$sp = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider;
|
$sp = new-object -TypeName System.Security.Cryptography.SHA1CryptoServiceProvider;
|
||||||
$fp = [System.IO.File]::Open("%(path)s", [System.IO.Filemode]::Open, [System.IO.FileAccess]::Read);
|
$fp = [System.IO.File]::Open("%(path)s", [System.IO.Filemode]::Open, [System.IO.FileAccess]::Read);
|
||||||
[System.BitConverter]::ToString($sp.ComputeHash($fp)).Replace("-", "").ToLower();
|
[System.BitConverter]::ToString($sp.ComputeHash($fp)).Replace("-", "").ToLower();
|
||||||
$fp.Dispose();
|
$fp.Dispose();
|
||||||
|
|
Loading…
Reference in a new issue