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.json
file - 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
Spinnaker environment:
- Spinnaker v1.20.6, v1.21.0 (assumption is v1.21.x but not validated)
- Halyard v1.36 to deploy Spinnaker (assumption is v1.36+ but not validated)
How to add a plugin to Spinnaker
Adding a plugin to Spinnaker consists of the following steps:
Add a plugin repository using Halyard
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:
hal plugins repository add <unique-repo-name> --url=<path-to-plugins.json-file>
For example:
hal plugins repository add spinnaker-plugin-examples \
--url=https://raw.githubusercontent.com/spinnaker-plugin-examples/examplePluginRepository/master/plugins.json
This action creates an entry in your Halconfig:
repositories:
spinnaker-plugin-examples:
id: spinnaker-plugin-examples
url: https://raw.githubusercontent.com/spinnaker-plugin-examples/examplePluginRepository/master/plugins.json
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:
hal plugins repository add all-the-plugins \
--url=https://raw.githubusercontent.com/aimeeu/all-the-plugins/master/repositories.json
You can also list, edit, and delete repositories. See the command reference for a complete list of parameters.
Don’t forget to hal deploy apply
to apply your configuration changes.
List, edit, and delete repositories
See the command reference to list, edit, or delete repositories.
Add a plugin using Halyard
Note: When Halyard adds a plugin to a Spinnaker installation, it adds the plugin repository information to each service. This means that when you restart Spinnaker, each service restarts, downloads the plugin, and checks if an extension exists for that service. Each service restarting is not ideal for large Spinnaker installations due to service restart times. Clouddriver can take an hour or more to restart if you have many accounts configured. Engineers are working to shorten restart times. See the Plugin configuration without Halyard section for how to avoid each service restarting.
After you have added your plugin repository, you can add your plugin to Spinnaker. The Halyard command is:
hal plugins add <unique-plugin-id> --extensions=<extension-name> \
--version=<version> --enabled=true
The plugin distributor should provide you with the unique-plugin-id
, extensions
, and version
values as well as any plugin configuration details. If you have to hunt for these values, you can find unique-plugin-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.
You add the pf4jStagePlugin
to Spinnaker like this:
hal plugins add Armory.RandomWaitPlugin --extensions=armory.randomWaitStage \
--version=1.1.4 --enabled=true
Halyard adds the plugin configuration to the .hal/config
file. Note the plugin’s empty config
collection.
spinnaker:
extensibility:
plugins:
Armory.RandomWaitPlugin:
id: Armory.RandomWaitPlugin
enabled: true
version: 1.1.14
extensions:
armory.randomWaitStage:
id: armory.randomWaitStage
enabled: true
config: {}
Halyard does not support configuring plugins. You should manually edit the Halconfig file for custom values. For example, pf4jStagePlugin
has a configurable defaultMaxWaitTime
, so you add that parameter to the plugin’s configuration in the config
collection section:
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
Note: hal plugins enable
and hal plugins disable
enable or disable all plugins, so use with caution.
Plugin configuration without Halyard
To avoid each service restarting and downloading the plugin, do not add the plugin using Halyard. 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: {}
The plugin developer should provide configuration details in YAML format. If not:
- Add the plugin using Halyard.
- Do not restart Spinnaker.
- Copy the plugin configuration from the Halconfig file.
- Paste the plugin configuration into the relevant service’s local file. Make sure configuration is in the format detailed above.
- Delete
the plugin by executing
hal plugins delete <unique-plugin-id>
. - Restart Spinnaker
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.
You can create or find the gate-local.yml
in the same place as the other Halyard configuration files. This is usually ~/.hal/default/profiles
on the machine where Halyard is running.
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 ID you used when you added the plugin to Spinnaker ( Add a plugin using Halyard section)unique-repo-name
: the plugin repository ID you used when you added the repository to Spinnaker ( Add a plugin repository using Halyard section)url
: the location of the plugin repository ( Add a plugin repository using Halyard section)
Redeploy Spinnaker
Remember to hal deploy apply
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 has been initiated and any new plugins would be added going forward.
You can ask for help with plugins in the
Spinnaker Slack
#plugins
channel.