Universal-Extension-Notes

1. Create a new Universal Extension Project

1.1. Create Project from Template

  1. Launch a new Visual Studio Code (VSC) Window

  2. Click on the Stonebranch Extension icon

    uip icon

    • this will open a tree view

  3. Expand the EXTENSION TEMPLATES tree view item.

    Init Proj

  4. Hover over the ue-task template and a folder+ icon will appear. Click the icon to initialize a new project

    Stonebranch tree view

  5. Select a new empty folder for the project.

  6. Set up 8 config values. The default values can be used except for the following:

    #1-Extension Name

    This is the Extension’s .zip file name (e.g. laz-uac-clone-ext.zip) that will also appear as the Extension name when viewing the Universal Template details in the gui.

    Universal Template details with Extension name highlighted

    New Universal Template details

    #5-Zip_safe

    false

    #6-Extension Owner Name

    This is the Extension Owner

    #7-Extension Org Name

    This is the Extension Owner’s Organization

    #8-Universal Template Name

    This is the label for the Extension e.g., LAZ-UAC-Clone-ext

    Universal Template details with Name highlighted

    New Universal Template details

  7. Click the Open in new workspace button

  8. After a moment, the following project structure will appear. The main extension file has been highlighted.

    Initial Proj Folder

    \src\extension.py is the main source file for the extension.

    Define the custom extension functionality in the extension_start method

1.2. Add the Universal Extension Base Package

  • The Universal Extension Base Package (universal_extension) is a Stonebranch provided Python package containing a collection of classes and functionality required to develop Universal Extensions. This package is distributed with the Universal Agent.

    The package resides within a zip archive (universal_extension.zip) and is installed to the following locations on hosts where the OpsWise Agent is installed:

    Table 1. Universal Extension Base Package locations
    Platform Location

    Windows

    C:\Program Files\Universal\UAGSrv\uext\universal_extension.zip

    Linux

    /opt/universal/uagsrv/uext/universal_extension.zip

  • Add this package to the project:

    1. Extract the zip file. This will result in a folder named universal_extension containing several Python files and sub folders

    2. Take the entire folder and copy it into the \src folder of the project

    3. The project structure should look like the following:

      base package

  • Add a path to the .vscode folder by editing the settings.json file.

    1. Open the settings.json file located in the .vscode folder.

    2. Add the following to python.analysis.extraPaths

      ".\\src",
      Example
      {
          "python.analysis.extraPaths": [
              ".\\src", (1)
              "C:\\Users\\username\\AppData\\Roaming\\Python",
              "c:\\source\\the-project\\.uip\\typings"
          ]
      }
      1 this is the new line

1.3. Configure Project Credential and URL

  • VSC will communicate with OpsWise via a user id which will be used to remotely update the extension and optionally remotely launch a Task based on the extension.

    1. Create a user e.g., lfops_web_servicer_ext with the following :

    2. Web Service Access = enabled

    3. User Roles: ops_universal_template_admin

    4. Permissions:

      Table 2. User ID permissions
      Type Operations Commands Name Unassigned to Business Service Business Services

      Agent

      Execute

      *

      Yes

      *

      Credential

      Execute

      *

      Yes

      *

      Task

      Read

      Launch

      *

      Yes

      *

      Task Instance

      Read

      ALL

      *

      Yes

      *

      Script

      Execute

      *

      Yes

      *

      Agent Cluster

      Read

      Resolve Agent Cluster

      *

      Yes

      *

    5. Via the palette menu (Ctrl+Shift+P) provide credential details for the new user:

      1. UIP: Set User ID

        Example User
        lfops_web_servicer_ext
      2. UIP: Set Password

    6. Set the webservices URL

      1. UIP: Set URL

        Example URL
        http://p-ubuntu-nas:8085/uc

        This is the Web Service URL and port - not the Web Browser URL and port

1.4. Deploy Extension to OpsWise Controller

  1. Click on the Stonebranch Extension icon

    • this will open a tree view

  2. Expand the Projects tree view item.

    • Your new project should appear here.

  3. Right mouse click on the project and select UIP: Push All

    This will:

    1. Build the project

    2. Create a distribution package.

    3. Push the distribution package to the OpsWise controller viewable as a Universal Template

  4. The new Univeral Template should appear in the OpsWise Universal Template list view tab.

    New Universal Template

    You may need to click the refresh button first
    If the new Univeral Template doesn’t appear in the list, create it manually.
  5. The Universal Template details window will look similar to the following:

    New Universal Template details

1.5. Run a Task based on the new Extension

  • The new extension will be available for use just like any other extension imported from the Stonebranch Market Place

    1. Create a new Task based on the new extension

    2. Now you can either launch the new Task normally via OpsWise or remotely via VSC

    3. To launch via VSC:

      1. First, via the palette menu (Ctrl+Shift+P) select UIP: Set Target Task and supply the name of the newly created Task.

      2. To launch the Task, via the palette menu, select UIP: Task Launch

    4. After the Task Instance has completed, any output will automatically be retrieved and displayed in the terminal window of VSC

      Sample Task Instance output
      PS .\source\UAC-UI-Test> & ".\Python\Python310\python.exe" -m uip.main task launch XS-Test-ext-Test
      Successfully launched the Universal task "XS-Test-ext-Test" with task instance id 17064474374868716927TMVIODBHHR8C.
      =======================================================================================
      Status: Success     (1)
      =======================================================================================
      
      
      EXTENSION Output:
      =================
      Hello Extension!    (2)
      
      STDOUT Output:
      ==============
      Hello STDOUT!       (3)
      
      
      STDERR Output:
      ==============
      [empty]             (4)
      1 Task status result
      2 Extension specific output not related to stdout or stderr
      3 Regular stdout output from the Task
      4 Regular stderr output from the Task

1.6. Edit

Edit the extension.py file located in the src folder

2. Field Types

3. Adding 3rd Party Python Package Dependencies

  • Universal Extensions can integrate third party Python Package.

    If authoring on a Windows desktop, the following will result in Windows based packages being included in the package.
    This may be an issue for Universal Extension bound for *Nix based systems.
    1. Edit the src\extension.yml file and confirm zip_safe is set to false.

      extension:
        name: ue-task
        version: "1.0.0"
        api_level: "1.4.0"
        requires_python: ">=2.6"
        zip_safe: false           (1)
      owner:
        name: Stonebranch
        organization: Stonebranch Inc.
      comments: |
        Created using ue-task template
      1 zip_safe should be false
    2. In order to add a particular Python Package, first identify a specific package version from the PyPi site

    3. Add the dependency as a package name and version to the requirements.txt file

      Example for the paramiko package
      paramiko
    4. Add the standard import statement to the extension.py file

      import statement
      import paramiko
    5. Build the project

      1. Click on the Stonebranch Extension icon

      2. On the project, right mouse click and select UIP: Push All

    6. After a successful build, the package and any co-requisites will appear in the \3pp folder

4. Debugging

  • Full documentation can be found here.

4.1. Install UE Bundle

  1. Download the latest universal_extension_bundle_2.x.x.zip file from the Stonebranch Customer Portal.

    This file will be referenced later…​
  2. Click on the Stonebranch Extension icon.

    uip icon

  3. Click on the bottom title bar where it says, UE Bundle not installed.

    UE Bundle Not Installed

  4. Select the latest version of the UE API.

    select ue api version

  5. Click the Yes button to install.

    UE Bundle Install prompt

  6. Click the Path to universal_extension_bundle…​ button.

    select path to UE Bundle

  7. Select the path where the universal_extension_bundle_2.x.x.zip file was downloaded.

  8. Now the Universal Extension Bundle version appears:

    UE Bundle Installed

4.2. Setup Debug Configuration

  1. Click on the Stonebranch Extension icon.

    uip icon

  2. Expand DEBUG CONFIGURATIONS

    DebugConfigurations item

  3. Click on the Add Configurations button

    DebugConfigurations AddConfigurations

    • This will open the configurations.yml file

  4. While the configurations.yml file is open for editing, add contents:

    1. Press cntrl+space

5. Dynamic Choice Fields

  • These choice fields will be available to "UE Task" types at definition time and allow the user to select values that are populated by the target agent system prior to task submission.

5.1. Create

  1. Via the OpsWise gui, edit the Universal Template and create a new field where the Type=Choice

    While fields can be created via VSC it’s easier to create them via the OpsWise gui
    Table 3. Sample Dynamic Choice Field
    Name Label Type

    test_dynamic_choice

    Dynamic Field

    Choice

5.2. Sync the Updated Template with VSC

  • Changes made in the gui need to be synchronized with the VSC project

    1. Click on the Stonebranch Extension icon

    2. On the project, click on the UIP: Pull button

5.3. Update Code

  1. Add the following import statement to the top of the code:

    from universal_extension.deco import dynamic_choice_command
  2. Create the function to return dynamic choice results

        @dynamic_choice_command("test_dynamic_choice")  (1)
        def the_dynamic_function(self,field):
            return ExtensionResult(
                rc=0,
                message="",
                values=["Value 0","Value 1","Value 2"]
                )
    1 The value supplied to the dynamic_choice_command decorator must match the field name of the associated Dynamic Choice field in the Controller’s Universal Template

5.4. Re-Build

  • Rebuild and push to OpsWise

    1. Click on the Stonebranch Extension icon

    2. On the project, click on the UIP: Push button