In this section we’ll provide a few handy examples of common driver operations. The intention is to grow this into a good source to copy paste common code from. All of the examples will be available in the DevGuide Examples repository under the common_driver_recipes folder.

Decrypting a password attribute

The password for logging into the device/app will be passed as an encrypted value to the driver as a part of the context object. In order to be able to use it to log in you’ll most likely need to decrypt it. To do that, you can use the CloudShellAPI function DecryptPassword.

See the code below for an example:

adding_examples/common_driver_recipes/src/driver.py view raw
def decrypt_password(self, context):
    """
    A simple example function
    :param ResourceCommandContext context: the context the command runs on
    """
    session = CloudShellAPISession(host=context.connectivity.server_address,
                                   token_id=context.connectivity.admin_auth_token,
                                   domain=context.reservation.domain)

    password = session.DecryptPassword(context.resource.attributes['Password']).Value

Updating the resource live status

The resource live status can be used to indicate the current state of the resource on the diagram. CloudShell comes with a pre-built collection of statuses you can use, and this collection of icons can also be extended if needed.

The following code will update the resource live status from offline to online:

adding_examples/common_driver_recipes/src/driver.py view raw
def update_resource_status(self, context):
    """
    A simple example function
    :param ResourceCommandContext context: the context the command runs on
    """
    session = CloudShellAPISession(host=context.connectivity.server_address,
                                   token_id=context.connectivity.admin_auth_token,
                                   domain=context.reservation.domain)

    session.SetResourceLiveStatus(context.resource.name, "Offline" )
    for i in range(0,10):
        session.SetResourceLiveStatus(context.resource.name, "Progress {status}".format(status=str(i*10)))


    session.SetResourceLiveStatus(context.resource.name, "Online" )

The full list of statuses can be found in the ServerUniversalSettings.xml file which you can find on the Quali Server machine under the %programdata%\QualiSystems\Settings\Global directory:

<ResourcesLiveStatus>
    <key name="Online">C:\ProgramData\QualiSystems\Portal\Content\Images\online.png</key>
    <key name="Stopped">C:\ProgramData\QualiSystems\Portal\Content\Images\online.png</key>
    <key name="Offline">C:\ProgramData\QualiSystems\Portal\Content\Images\offline.png</key>
    <key name="Error">C:\ProgramData\QualiSystems\Portal\Content\Images\error.png</key>
    <key name="Progress 0">C:\ProgramData\QualiSystems\Portal\Content\Images\progress0.png</key>
    <key name="Progress 10">C:\ProgramData\QualiSystems\Portal\Content\Images\progress10.png</key>
    <key name="Progress 20">C:\ProgramData\QualiSystems\Portal\Content\Images\progress20.png</key>
    <key name="Progress 30">C:\ProgramData\QualiSystems\Portal\Content\Images\progress30.png</key>
    <key name="Progress 40">C:\ProgramData\QualiSystems\Portal\Content\Images\progress40.png</key>
    <key name="Progress 50">C:\ProgramData\QualiSystems\Portal\Content\Images\progress50.png</key>
    <key name="Progress 60">C:\ProgramData\QualiSystems\Portal\Content\Images\progress60.png</key>
    <key name="Progress 70">C:\ProgramData\QualiSystems\Portal\Content\Images\progress70.png</key>
    <key name="Progress 80">C:\ProgramData\QualiSystems\Portal\Content\Images\progress80.png</key>
    <key name="Progress 90">C:\ProgramData\QualiSystems\Portal\Content\Images\progress90.png</key>
    <key name="Progress 100">C:\ProgramData\QualiSystems\Portal\Content\Images\progress100.png</key>
  </ResourcesLiveStatus>

Sending a message to the sandbox console

Another way to update the sandbox regarding an operation progress is to use the WriteMessageToReservationOutput function to display a message in the Sandbox console pane. We can easily modify the previous code to do that instead:

common_driver_recipes/src/driver.py view raw
def update_resource_status_to_console(self, context):
    """
    A simple example function
    :param ResourceCommandContext context: the context the command runs on
    """
    session = CloudShellAPISession(host=context.connectivity.server_address,
                                   token_id=context.connectivity.admin_auth_token,
                                   domain=context.reservation.domain)

    session.WriteMessageToReservationOutput(context.reservation.reservation_id, "Starting operation")
    for i in range(0, 10):
        session.WriteMessageToReservationOutput(context.reservation.reservation_id, "Progress at {status}%".format(status=str(i * 10)))

    session.WriteMessageToReservationOutput(context.reservation.reservation_id, "Done - service online")

Sending commands to a networking device

When adding a new command that requires communication with a networking device, such as a switch or router, you need to open a session to the device. An easy way to do that is by leveraging Quali’s shell framework (cloudshell-cli package). The framework can provide a session from a session pool via Telnet, SSH or TCP, based on the configuration saved in the CLI Connection Type attribute on the root resource.

See the code below for an example:

Ext_Cisco_NXOS_Shell_Package/Resource%20Drivers%20-%20Python/Generic%20Cisco%20NXOS%20Driver%20Version3%20Extended/cisco_nxos_resource_driver.py view raw
def some_command(self, context, command)
      logger = get_logger_with_thread_id(context)
      api = get_api(context)
      resource_config = create_networking_resource_from_context(shell_name=self.SHELL_NAME,
                                                                supported_os=self.SUPPORTED_OS,
                                                                context=context)
      cli_handler = CliHandler(self._cli, resource_config, logger, api)
      with cli_handler.get_cli_service(cli_handler.enable_mode) as session:
          session.send_command("some command")
          with session.enter_mode(cli_handler.config_mode) as config_session:
              config_session.send_command("some config command")