Plugin User Guide
Overview
Spinnaker uses PF4J-Update to load and manage plugins. These plugins can implement a PF4J extension point or be Spring components. See the Plugin Creators Guide for details.
Terms
plugins.json
- required file
- defines one to many plugins in a plugin repository
- each plugin definition has an id, description, provider, and a collection of releases (version, date, requires, sha512sum, state, url)
- the plugin developer provides access to this file
repositories.json
- optional file
- defines one to many plugin repositories
- each repository definition consists of a unique identifier and the path to a
plugins.jsonfile - the plugin developer may supply this file
Plugin requirements
- The plugin is either a Plugin Framework for Java (PF4J) plugin or a Spring plugin
- The plugin repository is a web location that Spinnaker can access, like a GitHub repository
How to add a plugin to Spinnaker
Adding a plugin to Spinnaker consists of the following steps:
Add a plugin repository
Note: Your plugins.json and repository.json files must be in a location that Spinnaker can access. Token authentication to private repositories is not supported. Consider storing your plugins and repository files in an AWS S3 bucket (or similar) instead of a private repository.
When you configure a repository, you tell Spinnaker where to find the plugins.json file that defines the plugins you
want to use. Each plugin repository entry in Spinnaker consists of a unique name and a URL.
If you want a repository to point to a single plugins.json file, you add it like this:
spinnaker:
extensibility:
repositories:
observabilityy-plugin:
url: https://raw.githubusercontent.com/armory-plugins/armory-observability-plugin-releases/master/plugins.json
It’s common to set this in the spinnaker-local.yml but it can be set on a per service basis for specific
services.
If you want a single plugin repository entry to point to multiple plugins.json files, you need to create a
repositories.json file that defines a collection of plugin repositories. The file format is:
[
{
"id": "<unique-repo-name>",
"url": "<url-of-plugins.json-file>"
}
]
For example:
[
{
"id": "spinnaker-plugin-examples",
"url": "https://raw.githubusercontent.com/spinnaker-plugin-examples/examplePluginRepository/master/plugins.json"
},
{
"id": "my-company-internal-plugins",
"url": "https://<my-company-internal-github>/<repo-name>/plugins.json"
},
{
"id": "my-plugins",
"url": "https://github.com/aimeeu/pluginRepository/blob/master/plugins.json"
}
]
Save your repositories.json file in a web location that Spinnaker can access. Then you can add a new plugin repository
using the repositories.json file:
spinnaker:
extensibility:
repositories:
all-the-plugins:
url: https://raw.githubusercontent.com/aimeeu/all-the-plugins/master/repositories.json
Don’t forget to apply your configuration changes by redeploying spinnaker.
Add a plugin
Note: when added to spinnaker-local.yml, each service attempts to load the plugin. This means that when you restart Spinnaker, each service restarts, downloads the plugin, and checks if an extension exists for that service.
After you have added your plugin repository, you can add your plugin to Spinnaker.
spinnaker:
extensibility:
repositories:
observabilityy-plugin:
url: https://raw.githubusercontent.com/armory-plugins/armory-observability-plugin-releases/master/repositories.json
deck-proxy:
enabled: true
plugins:
Armory.ObservabilityPlugin:
enabled: true
version: 0.1.1
plugins:
Armory.ObservabilityPlugin:
enabled: true
version: 1.5.0
config.metrics:
prometheus:
enabled: true
meterRegistryConfig:
armoryRecommendedFiltersEnabled: false
The plugin distributor should provide you with the plugin id LIKE Armory.ObservabilityPlugin and supported version
and If you have to hunt for these values, you can find id and version in
the plugins.json file, but you have to look at the code to find the value for
extensions. Search for the deprecated @ExtensionConfiguration or the
current @PluginConfiguration annotation. Both take a value, which is the extension name.
Example of the deprecated @ExtensionConfiguration annotation in the
pf4jStagePlugin
, which is written in Kotlin:
package io.armory.plugin.stage.wait.random
import com.netflix.spinnaker.kork.plugins.api.ExtensionConfiguration
@ExtensionConfiguration("armory.randomWaitStage")
data class RandomWaitConfig(var defaultMaxWaitTime: Int)
Example of the @PluginConfiguration annotation in the
Notification Plugin
, which is also written in Kotlin:
package io.armory.plugin.example.echo.notificationagent
import com.netflix.spinnaker.kork.plugins.api.PluginConfiguration
@PluginConfiguration("armory.httpNotificationService")
data class HTTPNotificationConfig(val url: String)
Plugin configuration variables are passed into the primary class constructor. If the plugin developer doesn’t specify configuration details, you can find key and type, or a configuration tree, by looking at the primary class constructor.
Another example using the Random Wait Plugin:
spinnaker:
extensibility:
plugins:
Armory.RandomWaitPlugin:
id: Armory.RandomWaitPlugin
enabled: true
version: 1.1.14
extensions:
armory.randomWaitStage:
id: armory.randomWaitStage
enabled: true
config:
defaultMaxWaitTime: 60
Plugin configuration
To avoid each service restarting
and downloading the plugin, do not add the plugin to the spinnaker-local.yml. Instead, configure the plugin in the service’s local file. For example, if your plugin extends Orca, add configuration to your orca-local.yml file.
spinnaker:
extensibility:
plugins:
<unique-plugin-id>:
id: <unique-plugin-id>
enabled: <true-false>
version: <version>
extensions:
<extension-name>:
id: <extension-name>
enabled: <true-false>
config: {}
Add a Deck proxy to Gate
If your plugin has a Deck component, you need to configure a deck-proxy so Gate knows where to find the plugin.
In your gate-local.yml add:
spinnaker:
extensibility:
deck-proxy:
enabled: true
plugins:
<unique-plugin-id>:
enabled: true
version: <version>
repositories:
<unique-repo-name>:
url: <url-to-repositories.json-or-plugins.json>
unique-plugin-id: the plugin IDunique-repo-name: the plugin repository IDurl: the location of the plugin repository
Redeploy Spinnaker
Remember to apply your manifest changes after you have finished configuring your plugin.
Deployment example
See the pf4jStagePlugin Deployment Example page for a walkthrough and troubleshooting.
Resources
A central repository for all Spinnaker plugins is available as an example but is no longer maintained or used.
You can ask for help with plugins in the
Spinnaker Slack
#plugins channel.