In this section, we’ll look at different recipes for creating and using CloudShell Sandboxes as a part of your CI/CD or other DevOps pipelines. In this context, we’ll concentrate on the use case of automating CloudShell externally from scripts or other platforms.

Available APIs

CloudShell currently supports two different sets of APIs which can be used to automate and integrate Sandboxes with DevOps.

  • The Python cloudshell-automation-api packge - This Python package contains an exhaustive set of APIs for anything from managing inventory and connections to administrating users and groups as well as managing sandboxes and blueprints.
  • The CloudShell Sandbox REST Apis - These are CloudShell’s next generation set of APIs. They are already using the latest terminology (sandboxes and blueprints instead of reservations and topologies/environments) and have advantages in performance and scaling. As of today, these APIs are limited to a specific set of commands focused on the workflow of starting and ending sandboxes. However, with each release more functionality is being added to the REST APIs and the intention is for this API set to eventually replace the Python package completely for most DevOps related workflows.

Which API to choose?

If the functionality you’re looking for is covered by the REST APIs it is recommended to use it over the Python package. If not, you can consider using the REST API for whatever subset of the required functionality it does offer and complement that with Python API calls.

Where are the APIs documented?

The REST API live documentation page is installed with CloudShell. To access it simply browse to the following default address: http://[CloudShellPortalAddress]:8032/api/v1/explore/. If you’re accessing the link from the CloudShell Portal machine itself, or from the CloudShell SDK edition machine, you can simply use “localhost” or “127.0.0.1”. The API documentation page allows you to test and experiment with the APIs as well as provide information on the different operations and parameters.

You can download the latest Python package reference from the CloudShell online help here.

When using the cloudshell-automation-api package, make sure to install the version of the API which is compatible with your CloudShell version. To make the task of finding the right version easier, this package follows a versioning schema different from other CloudShell packages. The major and minor version of the cloudshell-automation-api package will always match the CloudShell release its compatible with. Therefore, to install the latest compatible version you need to add these version requirements when installing from pip. For example, to install the latest cloudshell-automation-api compatible with CloudShell 7.0, run:

python -m pip install "cloudshell-automation-api>=7.0,<7.1"

To install the latest cloudshell-automation-api compatible with CloudShell 7.1, run:

python -m pip install "cloudshell-automation-api>=7.1,<7.2"

Starting and stopping a sandbox

The simplest and recommended way to start or stop a new sandbox instance from a blueprint is using the REST API. The REST API documentation page contains the details of the response and request format. The basic URLs of these operation is /blueprints/{blueprint_identifier}/start and /sandboxes/{sandbox_id}/stop.

Using the Rest API from Python

The following code sample demonstrates using the REST APIs for a simple flow - creating a sandbox from a blueprint, ensuring setup completes successfully then after running some tests.

devops_integration/sandbox_api_python_2_and_3/sandbox_api_example.py view raw
def main():
    """
    Example workflow of starting a sandbox, waiting for it to setup, then stopping it
    :return:
    """
    api_example = SandboxRESTAPI('localhost', '8032')
    api_example.login("admin", "admin", "Global")
    sandbox_id = api_example.start_sandbox('Simple blueprint', datetime.timedelta(hours=2), 'test_sandbox')
    sandox_details = api_example.wait_for_sandbox_setup(sandbox_id)
    run_some_tests_or_other_code(sandox_details)
    api_example.stop_sandbox(sandbox_id)
    api_example.wait_for_sandbox_teardown(sandbox_id)

This code uses a simple wrapper around the REST API which uses the requests package. You can find the source code for that implementation here:

Since sandboxes used this way are really a scope for testing. It can be beneficial to use Python’s with statement to ensure a sandbox is always set up and torn down properly with every usage. The following code wraps the Sandbox REST API as a context, ensuring proper cleanup and providing convenient access to the sandbox details.

devops_integration/sandbox_api_python_2_and_3/sandbox_context_example.py view raw
def main():
    """
    Example of using sandbox as a context
    """
    connectivity_params = QualiConnectivityParams('localhost', '8032', 'admin', 'admin', 'Global')

    with SandboxContext(connectivity_params, 'Simple blueprint', datetime.timedelta(hours=2)) as sandbox:
        run_some_tests_or_other_code(sandbox)

Both of the above examples are Python 2/3 compatible.

Sandbox REST API Missing and Upcoming Features

The Sandbox REST API has some known limitations. Currently (as of CloudShell 7.1GA) it does not support blueprint inputs and the creation of future (pending) reservation of sandboxes. The blueprint feature is currently “in the oven” and scheduled for a 7.2EA release. If your CloudShell environment does require those features you may need to fall back to the cloudshel-automation-api package API for sandbox reservation.

The following code demonstrates implementing the same basic flow using the Python package:

devops_integration/python_api/python_api_example.py view raw
def main():
    """
    Example workflow of starting a sandbox, waiting for it to setup, then stopping it
    :return:
    """

    session = CloudShellAPISession('localhost', "admin", "admin", "Global")
    # Create the sandbox
    sandbox = session.CreateImmediateTopologyReservation('test sandbox', owner='admin',
                                                         durationInMinutes=120,
                                                         topologyFullPath='Simple Blueprint1',
                                                         globalInputs=[UpdateTopologyGlobalInputsRequest('Target Cloud', 'AWS')]).Reservation

    sandbox_details = SandboxHelpers().wait_for_sandbox_setup(sandbox.Id, session,10)
    run_some_tests_or_other_code(session, sandbox_details)
    session.EndReservation(sandbox.Id)

Similar to the REST example, we can wrap the setup and teardown of the sandbox in a context object and take advantage of the Python with operator to simplify the flow.

devops_integration/python_api/python_api_context_example.py view raw
def main():
    """
    Example workflow of starting a sandbox, waiting for it to setup, then stopping it
    :return:
    """
    connectivity_params = QualiConnectivityParams(api_service_host='localhost', domain='Global',
                                                  password='admin', username='admin')
    inputs = BlueprintInputs(global_inputs=[UpdateTopologyGlobalInputsRequest('Target Cloud', 'AWS')])

    with SandboxContext(connectivity_params=connectivity_params,
                        blueprint_name='Simple Blueprint1', duration=120,
                        blueprint_inputs=inputs) as sandbox:
        run_some_tests_or_other_code(sandbox)

Executing Orchestration Commands

Executing orchestration commands from the REST API is not yet supported and is also scheduled for 7.2EA. Meanwhile, the Python package provides the necessary APIs to execute orchestration scripts in the sandbox:

devops_integration/python_api/python_api_example.py view raw
def run_some_tests_or_other_code(session, sandox_details):
    session.ExecuteEnvironmentCommand(reservationId=sandox_details.Id, commandName='Update Version',
                                      commandInputs=InputNameValue(Name='Version', Value='1.1'))
    pp = pprint.PrettyPrinter(indent=4)
    pp.pprint(jsonpickle.dumps(sandox_details))

    time.sleep(10)

Integrating with CI tools

The same basic workflow demonstrated in the above examples can be used to implement a plugin for CI frameworks such as Jenkins, Travis or TeamCity.

Several Quali community projects already provide readymade solutions for some CI tools.

The Sandbox-Jenkins-Plugin provides build steps for creating and ending sandboxes for Jenkins, as well as integration with the new PipeLines feature for continuous delivery and DevOps automation.

The Sandbox-Teamcity-Plugin provides similar build steps and integration for TeamCity.