From 9ee0114c9cef3e2bc735ac4ae9626bc205e42bf4 Mon Sep 17 00:00:00 2001 From: alexazarh Date: Wed, 13 Dec 2017 12:08:18 +0200 Subject: [PATCH 1/9] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 981be81..1a656d0 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,6 @@ # CustomScript-Shell + +## Links +* [Offline Package] (https://support.quali.com/hc/en-us/articles/231613247) From 6bf7377d124ef5a325f0640f102bfead27f19dd3 Mon Sep 17 00:00:00 2001 From: Nahum Timerman Date: Thu, 8 Feb 2018 12:59:35 +0200 Subject: [PATCH 2/9] fix issue with percent signs in environment variables --- .../cm/customscript/domain/windows_script_executor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package/cloudshell/cm/customscript/domain/windows_script_executor.py b/package/cloudshell/cm/customscript/domain/windows_script_executor.py index 4fdc829..f902404 100644 --- a/package/cloudshell/cm/customscript/domain/windows_script_executor.py +++ b/package/cloudshell/cm/customscript/domain/windows_script_executor.py @@ -132,7 +132,8 @@ def run_script(self, tmp_folder, script_file, env_vars, output_writer, print_out """ code = '' for key, value in (env_vars or {}).iteritems(): - code += '\n$env:%s = "%s"' % (key, str(value)) + code += '\n$env:%s = "%s"' % (key, str(value).replace('%', '%%')) # percent signs in environment variables + # will cause unexpected errors when using string interpolation code += """ $path = Join-Path "%s" "%s" Invoke-Expression "& '$path'" From 66546013b5d139cc605e13fcc756817793e734d0 Mon Sep 17 00:00:00 2001 From: Nahum Timerman Date: Thu, 8 Feb 2018 13:27:48 +0200 Subject: [PATCH 3/9] click --- .../domain/windows_script_executor.py | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/package/cloudshell/cm/customscript/domain/windows_script_executor.py b/package/cloudshell/cm/customscript/domain/windows_script_executor.py index f902404..d2ae328 100644 --- a/package/cloudshell/cm/customscript/domain/windows_script_executor.py +++ b/package/cloudshell/cm/customscript/domain/windows_script_executor.py @@ -114,11 +114,11 @@ def copy_script(self, tmp_folder, script_file): for bulk in bulks: encoded_bulk = base64.b64encode(bulk.encode("utf-8")) code = """ -$path = Join-Path "%s" "%s" -$data = [System.Convert]::FromBase64String("%s") +$path = Join-Path "{0}" "{1}" +$data = [System.Convert]::FromBase64String("{2}") Add-Content -value $data -encoding byte -path $path -""" - result = self._run_cancelable(code, tmp_folder, script_file.name, encoded_bulk) +""".format(tmp_folder, script_file.name, encoded_bulk) + result = self._run_cancelable(code) if result.status_code != 0: raise Exception(ErrorMsg.COPY_SCRIPT % result.std_err) @@ -135,10 +135,10 @@ def run_script(self, tmp_folder, script_file, env_vars, output_writer, print_out code += '\n$env:%s = "%s"' % (key, str(value).replace('%', '%%')) # percent signs in environment variables # will cause unexpected errors when using string interpolation code += """ -$path = Join-Path "%s" "%s" +$path = Join-Path "{0}" "{1}" Invoke-Expression "& '$path'" -""" - result = self._run_cancelable(code, tmp_folder, script_file.name) +""".format(tmp_folder, script_file.name) + result = self._run_cancelable(code) if print_output: output_writer.write(result.std_out) output_writer.write(result.std_err) @@ -164,8 +164,10 @@ def delete_temp_folder(self, tmp_folder): # self.logger.debug('Stderr:' + result.std_err) # return result - def _run_cancelable(self, txt, *args): - ps_code = txt % args + def _run_cancelable(self, ps_code): + """ + :type ps_code: str + """ self.logger.debug('PowerShellScript:' + ps_code) bat_code = 'powershell -encodedcommand %s' % base64.b64encode(ps_code.encode('utf_16_le')).decode('ascii') From a54412fb8707db2067c2185b4dbca8b8427ad81e Mon Sep 17 00:00:00 2001 From: Nahum Timerman Date: Thu, 8 Feb 2018 13:32:09 +0200 Subject: [PATCH 4/9] thing --- .../cm/customscript/domain/windows_script_executor.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package/cloudshell/cm/customscript/domain/windows_script_executor.py b/package/cloudshell/cm/customscript/domain/windows_script_executor.py index d2ae328..5e16abc 100644 --- a/package/cloudshell/cm/customscript/domain/windows_script_executor.py +++ b/package/cloudshell/cm/customscript/domain/windows_script_executor.py @@ -132,8 +132,7 @@ def run_script(self, tmp_folder, script_file, env_vars, output_writer, print_out """ code = '' for key, value in (env_vars or {}).iteritems(): - code += '\n$env:%s = "%s"' % (key, str(value).replace('%', '%%')) # percent signs in environment variables - # will cause unexpected errors when using string interpolation + code += '\n$env:%s = "%s"' % (key, str(value)) code += """ $path = Join-Path "{0}" "{1}" Invoke-Expression "& '$path'" From 4464cacc4ffa78751be09a968b14f31ca9007e39 Mon Sep 17 00:00:00 2001 From: Nahum Timerman Date: Thu, 8 Feb 2018 13:37:46 +0200 Subject: [PATCH 5/9] increase coverage --- package/tests/test_windows_script_executor.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/package/tests/test_windows_script_executor.py b/package/tests/test_windows_script_executor.py index 058846b..6ca887a 100644 --- a/package/tests/test_windows_script_executor.py +++ b/package/tests/test_windows_script_executor.py @@ -74,6 +74,12 @@ def test_copy_script_fail(self): # Run script + def test_get_expected_file_extensions(self): + executor = WindowsScriptExecutor(self.logger, self.host, self.cancel_sampler) + file_extensions = executor.get_expected_file_extensions() + self.assertTrue(file_extensions.length == 1) + self.assertTrue('.ps1' in file_extensions) + def test_run_script_success(self): executor = WindowsScriptExecutor(self.logger, self.host, self.cancel_sampler) output_writer = Mock() From 12c9aafe830c25d52fc34d9cf8d21d4044890f36 Mon Sep 17 00:00:00 2001 From: Nahum Timerman Date: Thu, 8 Feb 2018 13:43:41 +0200 Subject: [PATCH 6/9] $ --- package/tests/test_windows_script_executor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/tests/test_windows_script_executor.py b/package/tests/test_windows_script_executor.py index 6ca887a..7ca0529 100644 --- a/package/tests/test_windows_script_executor.py +++ b/package/tests/test_windows_script_executor.py @@ -77,7 +77,7 @@ def test_copy_script_fail(self): def test_get_expected_file_extensions(self): executor = WindowsScriptExecutor(self.logger, self.host, self.cancel_sampler) file_extensions = executor.get_expected_file_extensions() - self.assertTrue(file_extensions.length == 1) + self.assertTrue(len(file_extensions)==1) self.assertTrue('.ps1' in file_extensions) def test_run_script_success(self): From 49da759f0c24ad110ac4f9b8b860f0716ad22adc Mon Sep 17 00:00:00 2001 From: asafc64 Date: Thu, 8 Feb 2018 16:10:44 +0200 Subject: [PATCH 7/9] Better error msg when both username and password are empty --- .../cm/customscript/domain/linux_script_executor.py | 4 +++- package/tests/test_linux_script_executor.py | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/package/cloudshell/cm/customscript/domain/linux_script_executor.py b/package/cloudshell/cm/customscript/domain/linux_script_executor.py index d26ef52..c6311c2 100644 --- a/package/cloudshell/cm/customscript/domain/linux_script_executor.py +++ b/package/cloudshell/cm/customscript/domain/linux_script_executor.py @@ -47,8 +47,10 @@ def connect(self): key_stream = StringIO(self.target_host.access_key) key_obj = RSAKey.from_private_key(key_stream) self.session.connect(self.target_host.ip, username=self.target_host.username, pkey=key_obj) - else: + elif self.target_host.username: raise Exception('Both password and access key are empty.') + else: + raise Exception('Machine credentials are empty.') except NoValidConnectionsError as e: error_code = next(e.errors.itervalues(), type('e', (object,), {'errno': 0})).errno raise ExcutorConnectionError(error_code, e) diff --git a/package/tests/test_linux_script_executor.py b/package/tests/test_linux_script_executor.py index 4014a93..454f7ad 100644 --- a/package/tests/test_linux_script_executor.py +++ b/package/tests/test_linux_script_executor.py @@ -64,6 +64,12 @@ def test_no_password_nor_pen_file(self): executor.connect() self.assertEqual('Both password and access key are empty.', e.exception.inner_error.message) + def test_no_password_no_pen_file_no_username(self): + executor = LinuxScriptExecutor(self.logger, self.host, self.cancel_sampler) + with self.assertRaises(Exception) as e: + executor.connect() + self.assertEqual('Machine credentials are empty.', e.exception.inner_error.message) + def test_create_temp_folder_success(self): self._mock_session_answer(0,'tmp123','') result = self.executor.create_temp_folder() From f1da1e4b33a049b7501327508fc37bb1b6d77f86 Mon Sep 17 00:00:00 2001 From: Alex Azarh Date: Sun, 11 Feb 2018 14:59:18 +0200 Subject: [PATCH 8/9] fix versions and dependencies --- .travis.yml | 2 +- drivers/customscript_shell/drivermetadata.xml | 2 +- drivers/customscript_shell/requirements.txt | 2 +- drivers/version.txt | 2 +- package/requirements.txt | 2 +- package/version.txt | 2 +- version.txt | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3829d8e..7c77844 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ install: - pip install -r external_requirements.txt --extra-index-url https://pypi.python.org/simple - pip install -r test_requirements.txt --extra-index-url https://pypi.python.org/simple - pip install "cloudshell-shell-core>=3.1.0,<3.2.0" --extra-index-url https://testpypi.python.org/simple - - pip install "cloudshell-automation-api>=8.2.0.0,<8.2.1.0" --extra-index-url https://testpypi.python.org/simple + - pip install "cloudshell-automation-api>=8.3.0.0,<8.3.1.0" --extra-index-url https://testpypi.python.org/simple script: - pushd package diff --git a/drivers/customscript_shell/drivermetadata.xml b/drivers/customscript_shell/drivermetadata.xml index 78d8490..4f812f0 100644 --- a/drivers/customscript_shell/drivermetadata.xml +++ b/drivers/customscript_shell/drivermetadata.xml @@ -1,4 +1,4 @@ - + diff --git a/drivers/customscript_shell/requirements.txt b/drivers/customscript_shell/requirements.txt index b8dcea7..d618050 100644 --- a/drivers/customscript_shell/requirements.txt +++ b/drivers/customscript_shell/requirements.txt @@ -1,2 +1,2 @@ cloudshell-shell-core>=3.1.0,<3.2.0 -cloudshell-cm-customscript>=1.3.0,<1.4.0 +cloudshell-cm-customscript>=1.4.0,<1.5.0 diff --git a/drivers/version.txt b/drivers/version.txt index 589268e..e21e727 100644 --- a/drivers/version.txt +++ b/drivers/version.txt @@ -1 +1 @@ -1.3.0 \ No newline at end of file +1.4.0 \ No newline at end of file diff --git a/package/requirements.txt b/package/requirements.txt index 1cde969..1b9e97e 100644 --- a/package/requirements.txt +++ b/package/requirements.txt @@ -1,4 +1,4 @@ -cloudshell-automation-api>=8.2.0.0,<8.2.1.0 +cloudshell-automation-api>=8.3.0.0,<8.3.1.0 cloudshell-shell-core>=3.1.0,<3.2.0 pywinrm>=0.2.2 paramiko>=2.1.1 diff --git a/package/version.txt b/package/version.txt index 589268e..e21e727 100644 --- a/package/version.txt +++ b/package/version.txt @@ -1 +1 @@ -1.3.0 \ No newline at end of file +1.4.0 \ No newline at end of file diff --git a/version.txt b/version.txt index 589268e..e21e727 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.3.0 \ No newline at end of file +1.4.0 \ No newline at end of file From 7bdf09a021fb5e8fef10932331b37ab80af7ebf1 Mon Sep 17 00:00:00 2001 From: asafc64 Date: Wed, 14 Feb 2018 17:46:11 +0200 Subject: [PATCH 9/9] Better error when url leads to bad results --- .../cm/customscript/domain/script_downloader.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/package/cloudshell/cm/customscript/domain/script_downloader.py b/package/cloudshell/cm/customscript/domain/script_downloader.py index cd591fe..0f1a4e3 100644 --- a/package/cloudshell/cm/customscript/domain/script_downloader.py +++ b/package/cloudshell/cm/customscript/domain/script_downloader.py @@ -45,8 +45,17 @@ def download(self, url, auth): file_txt += ''.join(chunk) self.cancel_sampler.throw_if_canceled() + self._validate_response(response, file_txt) + return ScriptFile(name=file_name, text=file_txt) + def _validate_response(self, response, content): + if response.status_code < 200 or response.status_code > 300: + raise Exception('Failed to download script file: '+str(response.status_code)+' '+response.reason) + + if content.lstrip('\n\r').lower().startswith(''): + raise Exception('Failed to download script file: url points to an html file') + def _get_filename(self, response): file_name = None for header_value, pattern in self.filename_patterns.iteritems():