Winrm fixes for devel

* Include fixes for winrm connection plugin from v1 code
* Fixing shell plugin use
pull/11429/merge
James Cammarata 9 years ago
parent 2a8ab4ab3e
commit 2a5fbd8570

@ -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…
Cancel
Save