Skip to content

Commit

Permalink
Added support for old and new cloudshell-rest-api. Added possibility …
Browse files Browse the repository at this point in the history
…to pack shell without src folder
  • Loading branch information
alexquali committed Jul 30, 2024
1 parent 69ec48b commit e38a7b7
Show file tree
Hide file tree
Showing 50 changed files with 222 additions and 355 deletions.
1 change: 1 addition & 0 deletions dev_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pre-commit
tox
tox-factor
-r test_requirements.txt
-r requirements.txt
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ cookiecutter~=1.7.2
click~=7.1.2
pyyaml
terminaltables
cloudshell-rest-api>=8.2.3.1,<9
cloudshell-rest-api~=9.0.0
colorama
giturlparse.py
ruamel.yaml
Expand Down
5 changes: 2 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from setuptools import find_packages, setup

Expand Down Expand Up @@ -27,8 +26,8 @@ def get_file_content(file_name):
+ "\n\n"
+ get_file_content("HISTORY.rst"),
long_description_content_type="text/markdown",
author="QualiSystems",
author_email="info@qualisystems.com",
author="Quali",
author_email="info@quali.com",
url="https://github.com/QualiSystems/shellfoundry",
packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
package_data={"shellfoundry": ["data/*.yml", "data/*.json"]},
Expand Down
1 change: 0 additions & 1 deletion shellfoundry/models/install_config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

from shellfoundry.utilities.modifiers.configuration.password_modification import (
PasswordModification,
Expand Down
33 changes: 17 additions & 16 deletions shellfoundry/utilities/archive_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,21 @@ def make_archive(output_filename, archive_format, source_dir):
:param source_dir: Directory to scan for archiving
:return:
"""
if os.path.splitext(output_filename)[1] == "":
output_filename += ".zip"
output_dir = os.path.dirname(output_filename)
if output_dir and not os.path.exists(output_dir):
os.makedirs(output_dir)
relroot = source_dir
with zipfile.ZipFile(output_filename, "w", zipfile.ZIP_DEFLATED) as zip_f:
for root, dirs, files in os.walk(source_dir):
# add directory (needed for empty dirs)
zip_f.write(root, os.path.relpath(root, relroot))
for file in files:
filename = os.path.join(root, file)
if os.path.isfile(filename): # regular files only
arcname = os.path.join(os.path.relpath(root, relroot), file)
zip_f.write(filename, arcname)
if os.path.exists(source_dir):
if os.path.splitext(output_filename)[1] == "":
output_filename += ".zip"
output_dir = os.path.dirname(output_filename)
if output_dir and not os.path.exists(output_dir):
os.makedirs(output_dir)
relroot = source_dir
with zipfile.ZipFile(output_filename, "w", zipfile.ZIP_DEFLATED) as zip_f:
for root, dirs, files in os.walk(source_dir):
# add directory (needed for empty dirs)
zip_f.write(root, os.path.relpath(root, relroot))
for file in files:
filename = os.path.join(root, file)
if os.path.isfile(filename): # regular files only
arcname = os.path.join(os.path.relpath(root, relroot), file)
zip_f.write(filename, arcname)

return output_filename
return output_filename
27 changes: 18 additions & 9 deletions shellfoundry/utilities/cloudshell_api/client_wrapper.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

from cloudshell.rest.api import PackagingRestApiClient

Expand Down Expand Up @@ -44,14 +43,24 @@ def create_client(self, **kwargs):

def _create_client(self):
try:
client = PackagingRestApiClient(
ip=self._cs_config.host,
username=self._cs_config.username,
port=self._cs_config.port,
domain=self._cs_config.domain,
password=self._cs_config.password,
)
return client
try:
client = PackagingRestApiClient.login(
host=self._cs_config.host,
port=self._cs_config.port,
username=self._cs_config.username,
password=self._cs_config.password,
domain=self._cs_config.domain,
)
return client
except AttributeError:
client = PackagingRestApiClient(
ip=self._cs_config.host,
port=self._cs_config.port,
username=self._cs_config.username,
password=self._cs_config.password,
domain=self._cs_config.domain,
)
return client
except (HTTPError, Exception) as e:
if hasattr(e, "code") and e.code == 401:
if hasattr(e, "msg") and e.msg:
Expand Down
35 changes: 22 additions & 13 deletions shellfoundry/utilities/driver_generator.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
try:
from urllib.error import URLError
except ImportError:
Expand Down Expand Up @@ -65,7 +64,7 @@ def _generate_driver_data_model(
:param shell_name:
:return:
"""
url = "http://{0}:{1}/API/ShellDrivers/Generate".format(
url = "http://{}:{}/API/ShellDrivers/Generate".format(
cloudshell_config.host, cloudshell_config.port
)
token = client.token
Expand All @@ -76,7 +75,7 @@ def _generate_driver_data_model(
)

if response.status_code != 200:
error_message = "Code generation failed with code {0} and error {1}".format(
error_message = "Code generation failed with code {} and error {}".format(
response.status_code, response.text
)
click.echo(message=error_message, err=True)
Expand All @@ -85,25 +84,35 @@ def _generate_driver_data_model(
click.echo("Extracting data model ...")
with TempDirContext(remove_dir_on_error=False, prefix=shell_name) as temp_dir:
generated_zip = path.join(temp_dir, shell_filename)
click.echo("Writing temporary file {0}".format(generated_zip))
click.echo("Writing temporary file {}".format(generated_zip))
with open(generated_zip, "wb") as driver_file:
driver_file.write(response.content)

click.echo("Extracting generated code at {0}".format(destination_path))
click.echo("Extracting generated code at {}".format(destination_path))
with zipfile.ZipFile(generated_zip) as zf:
zf.extractall(destination_path)

@staticmethod
def _connect_to_cloudshell(cloudshell_config):
try:
client = PackagingRestApiClient(
ip=cloudshell_config.host,
username=cloudshell_config.username,
port=cloudshell_config.port,
domain=cloudshell_config.domain,
password=cloudshell_config.password,
)
return client
try:
client = PackagingRestApiClient.login(
host=cloudshell_config.host,
port=cloudshell_config.port,
username=cloudshell_config.username,
password=cloudshell_config.password,
domain=cloudshell_config.domain,
)
return client
except AttributeError:
client = PackagingRestApiClient(
ip=cloudshell_config.host,
port=cloudshell_config.port,
username=cloudshell_config.username,
password=cloudshell_config.password,
domain=cloudshell_config.domain,
)
return client
except URLError:
click.echo(
"Login to CloudShell failed. Please verify the credentials in cloudshell_config.yml", # noqa: E501
Expand Down
31 changes: 21 additions & 10 deletions shellfoundry/utilities/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,28 @@ def install(self, package_name, config):
:type config shellfoundry.models.install_config.InstallConfig
:return:
"""
host = config.host
port = config.port
username = config.username
password = config.password
domain = config.domain

package_full_path = os.path.join(os.getcwd(), "dist", package_name + ".zip")
click.echo(
"Installing package {0} into CloudShell at http://{1}:{2}".format(
package_full_path, host, port
"Installing package {} into CloudShell at http://{}:{}".format(
package_full_path, config.host, config.port
)
)
server = PackagingRestApiClient(host, port, username, password, domain)
server.import_package(package_full_path)

try:
client = PackagingRestApiClient.login(
host=config.host,
port=config.port,
username=config.username,
password=config.password,
domain=config.domain,
)
except AttributeError:
client = PackagingRestApiClient(
ip=config.host,
port=config.port,
username=config.username,
password=config.password,
domain=config.domain,
)

client.import_package(package_full_path)
43 changes: 29 additions & 14 deletions shellfoundry/utilities/shell_package_installer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

import json
import os
Expand All @@ -13,7 +12,14 @@
from urllib2 import HTTPError

from cloudshell.rest.api import PackagingRestApiClient
from cloudshell.rest.exceptions import FeatureUnavailable, ShellNotFoundException

try:
from cloudshell.rest.exceptions import FeatureUnavailable, ShellNotFound
except ImportError:
from cloudshell.rest.exceptions import (
FeatureUnavailable,
ShellNotFoundException as ShellNotFound,
)

from shellfoundry.exceptions import FatalError
from shellfoundry.utilities.config_reader import CloudShellConfigReader, Configuration
Expand Down Expand Up @@ -77,7 +83,7 @@ def install(self, path):
except FeatureUnavailable:
# try to update shell first
pass
except ShellNotFoundException:
except ShellNotFound:
# try to install shell
pass
except click.Abort:
Expand All @@ -98,7 +104,7 @@ def install(self, path):
) as pbar:
try:
client.update_shell(package_full_path)
except ShellNotFoundException:
except ShellNotFound:
self._increase_pbar(pbar, DEFAULT_TIME_WAIT)
self._add_new_shell(client, package_full_path)
except Exception as e:
Expand Down Expand Up @@ -145,7 +151,7 @@ def delete(self, shell_name):
raise click.ClickException(
"Delete shell command unavailable (probably due to CloudShell version below 9.2)" # noqa: E501
)
except ShellNotFoundException:
except ShellNotFound:
self._increase_pbar(pbar, DEFAULT_TIME_WAIT)
raise click.ClickException(
"Shell '{shell_name}' doesn't exist on CloudShell".format(
Expand All @@ -166,16 +172,25 @@ def _open_connection_to_quali_server(self, cloudshell_config, pbar, retry):
"Connection to CloudShell Server failed. "
"Please make sure it is up and running properly."
)

try:
client = PackagingRestApiClient(
ip=cloudshell_config.host,
username=cloudshell_config.username,
port=cloudshell_config.port,
domain=cloudshell_config.domain,
password=cloudshell_config.password,
)
return client
try:
client = PackagingRestApiClient.login(
host=cloudshell_config.host,
port=cloudshell_config.port,
username=cloudshell_config.username,
password=cloudshell_config.password,
domain=cloudshell_config.domain,
)
return client
except AttributeError:
client = PackagingRestApiClient(
ip=cloudshell_config.host,
port=cloudshell_config.port,
username=cloudshell_config.username,
password=cloudshell_config.password,
domain=cloudshell_config.domain,
)
return client
except HTTPError as e:
if e.code == 401:
raise FatalError(
Expand Down
2 changes: 0 additions & 2 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-

import os

TEST_DIR = os.path.dirname(__file__)
11 changes: 3 additions & 8 deletions tests/asserts.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os


def assertFileExists(obj, file_path):
obj.assertTrue(
os.path.exists(file_path),
msg="File/directory {0} does not exist".format(file_path),
)
obj.assertTrue(
os.path.isfile(file_path), msg="File {0} does not exist".format(file_path)
msg=f"File/directory {file_path} does not exist",
)
obj.assertTrue(os.path.isfile(file_path), msg=f"File {file_path} does not exist")


def assertFileDoesNotExist(obj, file_path):
obj.assertFalse(
os.path.exists(file_path), msg="File/directory {0} exists".format(file_path)
)
obj.assertFalse(os.path.exists(file_path), msg=f"File/directory {file_path} exists")
1 change: 0 additions & 1 deletion tests/helpers/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
# -*- coding: utf-8 -*-
8 changes: 1 addition & 7 deletions tests/helpers/mocking_extensions.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import inspect
import sys

if sys.version_info >= (3, 0):
from unittest.mock import MagicMock
else:
from mock import MagicMock
from unittest.mock import MagicMock


def bootstrap():
Expand Down
8 changes: 1 addition & 7 deletions tests/test_bootstrap.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import traceback
import unittest
from unittest.mock import MagicMock, patch

from click.testing import CliRunner

if sys.version_info >= (3, 0):
from unittest.mock import MagicMock, patch
else:
from mock import MagicMock, patch

from shellfoundry.bootstrap import (
config,
delete,
Expand Down
Loading

0 comments on commit e38a7b7

Please sign in to comment.