Managing Morpheus Plugins via REST API

The Morpheus platform supports the ability to extend the platform’s native functionality using plugins. Plugins are developed in Groovy or Java and are used to create custom reports, IPAM integrations, UI customizations, and more. During the development process, plugin developers need to test the plugin’s functionality on a Morpheus installation. The 5.4.12 release of Morpheus added a feature to enable plugin developers to automate the lifecycle management of plugins via the REST API. This unlocks the ability to automate the upload of new plugin versions without manually uploading it via the UI or manually configuring the plugin’s settings. This enables fully automated acceptance testing of plugins during local development or as part of a CI/CD pipeline.

In this blog post you’ll learn how to use the Morpheus REST API to manage Morpheus plugins.

Uploading a Plugin

Manually installing a plugin in the Morpheus platform involves uploading the jar file via the web based file browser. This becomes tedious during the development of a plugin when multiple small changes are constantly being made and need to be tested. The following is an example python script that could be used to automate upload a compiled plugin jar file.

The following examples use the plugin from this repository: https://github.com/martezr/morpheus-hashicorp-consul-plugin

Example Upload Python Script

The following script is for reference purposes.

import requests
import urllib3

morpheus_hostname    = "devmorpheus.morpheus.local"
verify_ssl           = False
access_token         = "8fa0b259-4cdf-7228-3b1e-cfc22b54fdc8"
plugin_name          = "morpheus-hashicorp-consul-plugin"
plugin_version       = "1.0.0"
plugin_file_name     = plugin_name + "-" + plugin_version + ".jar"
plugin_file_path     = "build/libs/"
plugin_relative_path = plugin_file_path + plugin_file_name

# If ssl verification is disabled then suppress SSL warnings
if not verify_ssl:
    urllib3.disable_warnings()


url = "https://" + morpheus_hostname + "/api/plugins/upload"

headers = {
    "accept": "application/json",
    "authorization": "Bearer " + access_token
}

files = {"file": (plugin_file_name, open(plugin_relative_path, "rb"), "application/java-archive")}

response = requests.post(url, files=files, headers=headers, verify=verify_ssl)

print(response.text)

The plugin should be visible under the Administration > Integrations > Plugins section of the Morpheus UI similar to the screenshot displayed below.

morpheus plugins list

API Reference: https://apidocs.morpheusdata.com/v5.4.12/reference/uploadplugin

Update Plugin Settings

Once a plugin has been installed there are often settings for configuring the behavior of the plugin. The API endpoint for updating an existing plugin requires the ID of the plugin entry. In this case the example script will use the list plugins API call in a two step process to find the ID of the desired plugin by name. The plugin used in this example has a configuration setting for setting the URL for where to reach the HashiCorp Consul server.

Plugin Name

The API call expects the display name of the plugin which is the name displayed in the Morpheus UI and defined in the initialize section of the plugin code.

Plugin Settings

The plugin settings are defined using the value of the fieldName attribute for the plugin’s option types.

Example Update Python Script

The following script is for reference purposes.

import requests
import urllib3
import json

morpheus_hostname    = "devmorpheus.morpheus.local"
verify_ssl           = False
access_token         = "8fa0b259-4cdf-7228-3b1e-cfc22b54fdc8"
plugin_name          = "morpheus-hashicorp-consul-plugin"
plugin_version       = "1.0.0"
plugin_file_name     = plugin_name + "-" + plugin_version + ".jar"
plugin_file_path     = "build/libs/"
plugin_relative_path = plugin_file_path + plugin_file_name
plugin_display_name  = "Consul Integration Plugin"
consul_server_url    = "http://consul.morpheus.local:8500"


# If ssl verification is disabled then suppress SSL warnings
if not verify_ssl:
    urllib3.disable_warnings()

# Find the ID of the existing plugin by name
listUrl = "https://" + morpheus_hostname + "/api/plugins?max=25&offset=0&sort=name&direction=asc&name=" + plugin_display_name

headers = {
    "accept": "application/json",
    "authorization": "Bearer " + access_token
}

response = requests.get(listUrl, headers=headers, verify=verify_ssl)
jsonPayload = json.loads(response.text)
pluginId = jsonPayload["plugins"][0]["id"]

# Update the existing plugin settings
updateUrl = "https://" + morpheus_hostname + "/api/plugins/" + str(pluginId)

headers = {
    "accept": "application/json",
    "authorization": "Bearer " + access_token
}

configPayload = {}
configPayload["plugin"] = {}
configPayload["plugin"]["config"] = {}
configPayload["plugin"]["config"]["consulServerUrl"] = consul_server_url

response = requests.put(updateUrl, headers=headers, data=json.dumps(configPayload), verify=verify_ssl)

print(response.text)

The SERVER URL plugin setting is set using the REST API call.

API Reference: https://apidocs.morpheusdata.com/v5.4.12/reference/updateplugin

Delete a Plugin

Removing or deleting a plugin is also possible using the REST API. This might be necessary as part of the cleanup process of a development pipeline.

Example Delete Python Script

The following script is for reference purposes.

import requests
import urllib3

morpheus_hostname    = "devmorpheus.morpheus.local"
verify_ssl           = False
access_token         = "8fa0b259-4cdf-7228-3b1e-cfc22b54fdc8"
plugin_name          = "morpheus-hashicorp-consul-plugin"
plugin_version       = "1.0.0"
plugin_file_name     = plugin_name + "-" + plugin_version + ".jar"
plugin_file_path     = "build/libs/"
plugin_relative_path = plugin_file_path + plugin_file_name
plugin_display_name  = "Consul Integration Plugin"
consul_server_url    = "http://consul.morpheus.local:8500"

# If ssl verification is disabled then suppress SSL warnings
if not verify_ssl:
    urllib3.disable_warnings()


# Find the ID of the existing plugin by name
listUrl = "https://" + morpheus_hostname + "/api/plugins?max=25&offset=0&sort=name&direction=asc&name=" + plugin_display_name

headers = {
    "accept": "application/json",
    "authorization": "Bearer " + access_token
}

response = requests.get(listUrl, headers=headers, verify=verify_ssl)
jsonPayload = json.loads(response.text)
pluginId = jsonPayload["plugins"][0]["id"]

# Delete the existing plugin
deleteUrl = "https://" + morpheus_hostname + "/api/plugins/" + str(pluginId)

response = requests.delete(deleteUrl, headers=headers, verify=verify_ssl)

print(response.text)

API Reference: https://apidocs.morpheusdata.com/v5.4.12/reference/removeplugin

This blog post walked through how the new plugin API endpoint could be used to manage the lifecycle of Morpheus plugins.

Join the Morpheus Community

Join the Morpheus community and engage other Morpheus community users to learn more about ways to use the platform. Also, downloading the Morpheus Community Edition lets you fully experience the Morpheus platform including nearly all features and capabilities! Register at Morpheus Hub and try it in your home lab or test environment today!

X