def _get_script_arguments(self, named_args=None, positional_args=None): """ Builds a string of named and positional arguments in PowerShell format, which are passed to the script. :param named_args: Dictionary with named arguments :type named_args: ``dict``. :param positional_args: List of positional arguments :type positional_args: ``str`` :rtype: ``str`` """ cmd_parts = [] if positional_args: cmd_parts.append(positional_args) if named_args: for (arg, value) in six.iteritems(named_args): arg = quote_windows(arg) if value is None or (isinstance(value, six.string_types) and len(value) < 1): LOG.debug('Ignoring arg %s as its value is %s.', arg, value) continue if isinstance(value, bool): if value: cmd_parts.append('-%s' % (arg)) else: cmd_parts.append('-%s:$false' % (arg)) elif isinstance(value, (list, tuple)) or hasattr(value, '__iter__'): # Array support, pass parameters to shell script cmd_parts.append('-%s %s' % (arg, ','.join(value))) else: cmd_parts.append('-%s %s' % (arg, quote_windows(str(value)))) return ' '.join(cmd_parts)
def _run_script(self, script_path, arguments=None): """ :param script_path: Full path to the script on the remote server. :type script_path: ``str`` :param arguments: The arguments to pass to the script. :type arguments: ``str`` """ if arguments is not None: command = '%s %s %s' % (POWERSHELL_COMMAND, quote_windows(script_path), arguments) else: command = '%s %s' % (POWERSHELL_COMMAND, quote_windows(script_path)) args = self._get_winexe_command_args(host=self._host, username=self._username, password=self._password, command=command) LOG.debug('Running script "%s"' % (script_path)) # Note: We don't send anything over stdin, we just create an unused pipe # to avoid some obscure failures exit_code, stdout, stderr, timed_out = run_command( cmd=args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, timeout=self._timeout) extra = {'exit_code': exit_code, 'stdout': stdout, 'stderr': stderr} LOG.debug('Command returned', extra=extra) return exit_code, stdout, stderr, timed_out
def _run_script(self, script_path, arguments=None): """ :param script_path: Full path to the script on the remote server. :type script_path: ``str`` :param arguments: The arguments to pass to the script. :type arguments: ``str`` """ if arguments is not None: command = '%s %s %s' % (POWERSHELL_COMMAND, quote_windows(script_path), arguments) else: command = '%s %s' % (POWERSHELL_COMMAND, quote_windows(script_path)) args = self._get_winexe_command_args(host=self._host, username=self._username, password=self._password, command=command) LOG.debug('Running script "%s"' % (script_path)) # Note: We don't send anything over stdin, we just create an unused pipe # to avoid some obscure failures exit_code, stdout, stderr, timed_out = run_command(cmd=args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, timeout=self._timeout) extra = {'exit_code': exit_code, 'stdout': stdout, 'stderr': stderr} LOG.debug('Command returned', extra=extra) return exit_code, stdout, stderr, timed_out
def _upload_file(self, local_path, base_path): """ Upload provided file to the remote server in a temporary directory. :param local_path: Local path to the file to upload. :type local_path: ``str`` :param base_path: Absolute base path for the share. :type base_path: ``str`` """ file_name = os.path.basename(local_path) temporary_directory_name = str(uuid.uuid4()) command = 'mkdir %s' % (quote_windows(temporary_directory_name)) # 1. Create a temporary dir for out scripts (ignore errors if it already exists) # Note: We don't necessary have access to $TEMP so we create a temporary directory for our # us in the root of the share we are using and have access to args = self._get_smbclient_command_args(host=self._host, username=self._username, password=self._password, command=command, share=self._share) LOG.debug('Creating temp directory "%s"' % (temporary_directory_name)) exit_code, stdout, stderr, timed_out = run_command(cmd=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, timeout=CREATE_DIRECTORY_TIMEOUT) extra = {'exit_code': exit_code, 'stdout': stdout, 'stderr': stderr} LOG.debug('Directory created', extra=extra) # 2. Upload file to temporary directory remote_path = PATH_SEPARATOR.join([temporary_directory_name, file_name]) values = { 'local_path': quote_windows(local_path), 'remote_path': quote_windows(remote_path) } command = 'put %(local_path)s %(remote_path)s' % values args = self._get_smbclient_command_args(host=self._host, username=self._username, password=self._password, command=command, share=self._share) extra = {'local_path': local_path, 'remote_path': remote_path} LOG.debug('Uploading file to "%s"' % (remote_path)) exit_code, stdout, stderr, timed_out = run_command(cmd=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, timeout=UPLOAD_FILE_TIMEOUT) extra = {'exit_code': exit_code, 'stdout': stdout, 'stderr': stderr} LOG.debug('File uploaded to "%s"' % (remote_path), extra=extra) full_remote_file_path = base_path + '\\' + remote_path full_temporary_directory_path = base_path + '\\' + temporary_directory_name return full_remote_file_path, full_temporary_directory_path
def _get_share_absolute_path(self, share): """ Retrieve full absolute path for a share with the provided name. :param share: Share name. :type share: ``str`` """ command = 'net share %s' % (quote_windows(share)) args = self._get_winexe_command_args(host=self._host, username=self._username, password=self._password, command=command) LOG.debug('Retrieving full absolute path for share "%s"' % (share)) exit_code, stdout, stderr, timed_out = run_command( cmd=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, timeout=self._timeout) if exit_code != 0: msg = 'Failed to retrieve absolute path for share "%s"' % (share) raise Exception(msg) share_info = self._parse_share_information(stdout=stdout) share_path = share_info.get('path', None) if not share_path: msg = 'Failed to retrieve absolute path for share "%s"' % (share) raise Exception(msg) return share_path
def _get_share_absolute_path(self, share): """ Retrieve full absolute path for a share with the provided name. :param share: Share name. :type share: ``str`` """ command = 'net share %s' % (quote_windows(share)) args = self._get_winexe_command_args(host=self._host, username=self._username, password=self._password, command=command) LOG.debug('Retrieving full absolute path for share "%s"' % (share)) exit_code, stdout, stderr, timed_out = run_command(cmd=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, timeout=self._timeout) if exit_code != 0: msg = 'Failed to retrieve absolute path for share "%s"' % (share) raise Exception(msg) share_info = self._parse_share_information(stdout=stdout) share_path = share_info.get('path', None) if not share_path: msg = 'Failed to retrieve absolute path for share "%s"' % (share) raise Exception(msg) return share_path
def test_quote_windows(self): arguments = [ "foo", "foo bar", "foo1 bar1", '"foo"', '"foo" "bar"', "'foo bar'" ] expected_values = [ """ foo """, """ "foo bar" """, """ "foo1 bar1" """, """ \\"foo\\" """, """ "\\"foo\\" \\"bar\\"" """, """ "'foo bar'" """, ] for argument, expected_value in zip(arguments, expected_values): actual_value = quote_windows(value=argument) expected_value = expected_value.lstrip() self.assertEqual(actual_value, expected_value.strip())
def _delete_file(self, file_path): command = 'rm %(file_path)s' % {'file_path': quote_windows(file_path)} args = self._get_smbclient_command_args(host=self._host, username=self._username, password=self._password, command=command, share=self._share) exit_code, _, _, _ = run_command(cmd=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, timeout=DELETE_FILE_TIMEOUT) return exit_code == 0
def _delete_directory(self, directory_path): command = 'rmdir %(directory_path)s' % {'directory_path': quote_windows(directory_path)} args = self._get_smbclient_command_args(host=self._host, username=self._username, password=self._password, command=command, share=self._share) LOG.debug('Removing directory "%s"' % (directory_path)) exit_code, _, _, _ = run_command(cmd=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, timeout=DELETE_DIRECTORY_TIMEOUT) return exit_code == 0
def test_quote_windows(self): arguments = [ 'foo', 'foo bar', 'foo1 bar1', '"foo"', '"foo" "bar"', "'foo bar'" ] expected_values = [ """ foo """, """ "foo bar" """, """ "foo1 bar1" """, """ \\"foo\\" """, """ "\\"foo\\" \\"bar\\"" """, """ "'foo bar'" """ ] for argument, expected_value in zip(arguments, expected_values): actual_value = quote_windows(value=argument) expected_value = expected_value.lstrip() self.assertEqual(actual_value, expected_value.strip())