5.1 Developing Kaholo Plugins

About Kaholo Plugins

Kaholo plugins are JavaScript applications that if correctly arranged and packaged can be installed in the Kaholo platform to extend functionality. Kaholo plugins are most commonly used for a few different purposes:

  • To provide integration with 3rd party systems, e.g. Amazon Web Services, Atlassian Jira, or GitHub
  • To provide a CLI capability, e.g. Maven, Terraform, or Ansible
  • To provide parameterized GUI access to basic tools, e.g. Bash Commands, FTP, Zip, or File Handling

Once installed, each plugin may appear one or more times in your Kaholo Pipelines as Actions, available in the Design page. The Action offers a collection of methods, each with configurable parameters. The methods are executed by the node.js Kaholo Agent when the pipeline is run. Plugins may also publish a result to “Final Result” on the Kaholo Execution Results Page, which is then accessible in the code layer. This allows the plugin to be orchestrated in the pipeline like any other Action, for example conditionally carrying out other actions based on the result.

There are over 100 plugins already available in the Kaholo Github Site. Instructions to install a plugin can be found in Install.md.

The Kaholo Template Plugin

A simple example plugin is the Kaholo Plugin Template.

This plugin is developed and maintained as a template repository for the development of other plugins. It is also a working Kaholo “Hello World” plugin. Because it has all the necessary parts in correct arrangement, it can be downloaded, installed, and used in Kaholo without modification.

Kaholo Plugin Components

A Kaholo Plugin consists of the following components:

  • config.json – The file containing all of the plugin’s configurations. This includes the settings fields, auth (Accounts), methods and their parameters, and metadata for the plugin like its name and description. See Also – JSON Schema for config.json
  • package.json – The file containing the npm packages configuration.
  • app.js – The file containing the code for all of the plugin’s external methods declared in the config.json file. This file’s name must match what is declared as “main” in the plugin metadata declared in config.json.
  • logo.png – A 512×512 pixel image file containing the icon that will be shown to users for the plugin when designing pipelines and various other places. This file’s name must match what is declared as “imgUrl” in the plugin metadata declared in config.json.
  • autocomplete.js (Optional) – A file containing all autocomplete functions, in case any autocomplete parameters were declared in the config.json file. Autocomplete parameters run functions to determine which values should populate a drop-down selection. For example, if the method is going to shut down a virtual machine, an autocomplete function might provide a list of running virtual machines to choose from. Without autocomplete, the user would have to know or find the name/id of the virtual machine and enter or paste that into a plain text parameter. Autocomplete is therefore a convenience, not a requirement.
  • Plugin Code

    All plugin code should be written in JavaScript. You should export all of your external methods from the file specified as “main” in config.json, e.g. app.js.

    The Kaholo Server expects all external methods that can be used by Kaholo users to be async. Each method declared in the config.json file needs to be in the following format:

        async function apply(action, settings) {
            >> some code here <<
        }
    

    Both action and settings are always sent as an input, and are objects containing all metadata and params of the action, and all of the plugin’s settings. You can reach each parameter or setting using action.params.paramName or settings.settingName.

    Autocomplete Parameters

    In config.json, an autocomplete method uses three method-level metadata to identify itself as an autocomplete function and declare which function in autocomplete.js should be used, for example:

        "type": "autocomplete",
        "autocompleteType": "function",
        "functionName": "listRegions",
    

    The fuction named in functionName must be exported in the file where it is coded.

        function listRegions(query = "") {
             >> some code here <<
             return filterItemsByQuery(autocompleteList, query);
          }
    
        module.exports = {listRegions};
    

    Autocomplete parameters store their value in the format of an object with two fields:

      id – A unique identifier not shown to the user but accessible from the plugin code.
      value – The text shown to the user in the Kaholo UI as a drop-down menu item. This is also accessible from the plugin code.

    Resolving Dependencies (npm packages)

    Kaholo plugins make use of npm packages to resolve and install dependencies. This is managed using the npm configuration file package.json as described on the npm Docs website. For example the package.json for the CSV plugin shows it depends on Kaholo’s plugin library, @kaholo/plugin-library, and lodash.

    Kaholo CSV plugin’s package.json

        {
            "name": "kaholo-plugin-csv",
            "description": "CSV plugin for Kaholo",
            "main": "app.js",
            "scripts": {
              "lint": "npx eslint .",
              "lint:fix": "npx eslint . --fix"
            },
            "author": "Kaholo team (Roy Talyosef)",
            "license": "ISC",
            "devDependencies": {
              "eslint": "8.16.0",
              "eslint-config-airbnb-base": "15.0.0",
              "eslint-plugin-import": "2.26.0"
            },
            "dependencies": {
              "@kaholo/plugin-library": "^1.3.0",
              "lodash": "4.17.21"
            }
        }
    

    Kaholo Plugin Library

    There is a library of commonly needed plugin functions available in the Kaholo Plugin Library. This is regularly published as an npm package. To use these functions simply list the plugin library as a dependency in package.json and then reference the library in code, for example in app.js:

        const kaholoPluginLibrary = require("@kaholo/plugin-library");
    

    Coming Soon – Kaholo Plugin Library documentation.

    Kaholo Plugin best practices

    Here are a few guidelines to make Kaholo plugins that are useful to wide audiences, easier to maintain, and less likely to be broken by future releases of Kaholo.

    • Ideally plugins work on both Linux and Windows Kaholo agents.
    • Plugins should be developed in the context of real-world pipelines, i.e. with all commonly used parameters and methods – not only those needed for a specific use case.
    • Order parameters with required ones first, then commonly used ones, and finally rarely used parameters last. This improves usability.
    • Set parameter default values where helpful (“default” in config.json).
    • Mark parameters that are absolutely required for a method to work as required ("required": true in config.json). Booleans needn’t be required because even left unconfigured and with no default they already have a valid value (false).
    • Consider using the Kaholo Accounts feature (“auth” in config.json) to consolidate parameters when:
      • The same parameter(s) are required for most methods of the plugin.
      • The parameters are likely to require the same values for every Action/Pipeline.
      • Configuring the parameters on an Action-by-Action basis is repetetive and tedius.
      • Parameters involve authorization – names, passwords, tokens, etc.
      • Two or more parameters are related such that changing any one parameter renders the others invalid – for example if username is changed, password most likely must also change.
      • Parameters in the Account may be omitted at the Action level without negatively impacting use cases.
    • Consider using the Kaholo Plugin Settings feature (“settings” in config.json) to allow parameters to have defaut values when:
      • Having a default value automatically populated at the Action level would be decidedly convenient for the end user(s), but may at times also need to be overridden by user input.
      • The parameter seems appropriate for the Kaholo Accounts feature but for any reason doesn’t quite work there.

    Kaholo Plugins that run in Docker

    A useful strategy for Kaholo plugins is to run methods within a Docker container and then to destroy the container once the method completes. This is such a common design that it has been incorporated into the Kaholo Plugin Library for easy re-use. Any plugin that requires some CLI, tool, or other software package (beyond npm dependencies) to be installed in order to work is a good candidate for this design. Since the Kaholo agent is typically deployed already as a docker/kubernetes container, this does mean running a docker container within another container. This takes only a second or two to complete, assuming the docker image is already available in the Kaholo agent’s Docker cache.

    This serves several purposes:

    • Runs each time within a fresh instance of a purpose-built container for consistent and reliable outcomes regardless of the state or version of the Kaholo agent node
    • Allows easier management of Kaholo agents because myriad software components needn’t be installed directly on the agent – only Docker
    • Lowers disk space footprint of agents, depending on how many docker images are ultimately cached for use
    • Simplifies optionally running multiple version of a dependent software package without conflicts
    • Allows for easy upgrade to latest version of docker image
    • When plugin method completes, sensitive materials such as caches and credentials used by the method may be destroyed along with the docker container for improved security

    However there are a few caveats as well:

    • The first time a Kaholo Plugin using docker is run, there is a significant delay as the docker image is downloaded to the agent’s docker cache, /var/lib/docker.
    • Files and configuration on the Kaholo Agent are not available within the docker image unless explicitly mounted as a docker volume.
    • Output of methods written to disk get destroyed unless written to mounted parts of the Kaholo Agent’s filesystem.

    See Also – Development of Kaholo Plugins using Docker