provision: github.com/digitalrebar/provision/plugin Index | Files | Directories

package plugin

import "github.com/digitalrebar/provision/plugin"

Package plugin is used to write plugin providers in Go. It provides the framework for the rest of the plugin provider code, along with a set of interfaces that you app can satisfy to implement whatever custom behaviour the plugin provider needs to implement.

A plugin provider is an executable that provides extensions to the base functionality in dr-provision. This can be done in several different ways, depending on the functionality the plugin provider needs to implement:

1. Injecting custom content bundles into dr-provision to provide

additional tasks, params, etc.

2. Implementing additional per-object Actions that can be used for

a wide variety of things.

3. Providing additional files in the files/ space of the static file server.

4. Listening to the event stream from dr-provision to take action

whenever any number of selected events happen.

5. Define new object types that dr-provision will store and manage.

github.com/digitalrebar/provision/cmds/incrementer provides a fully functional implementation of a basic plugin provider that you can use as an example and as a base for implementing your own plugin providers.

github.com/digitalrebar/provision-plugins contains several production ready plugin provider implementations that you can use as a reference for implementing more advanced behaviours.

At a higher level, a plugin provider is an application that has 3 ways of being invoked:

1. plugin_provider define

When invoked with a single argument of define, the plugin provider must
print the models.PluginProvider definition for the plugin provider in
JSON format on stdout.

2. plugin_provider unpack /path/to/filespace/for/this/provider

When invoked with unpack /path, the plugin provider must unpack any
embedded assets (extra executables and other artifacts like that) into
the path passed in as the argument.  Note that this does not include
the embedded content pack, which is emitted as part of the define
command.

3. plugin_provider listen /path/to/client/socket /path/to/server/socket

When invoked with listen, the plugin client must open an HTTP client
connection on the client socket to post events and status updates back
to dr-provision, and listen with an HTTP server on the server socket
to receive action requests, stop requests, and events from dr-provision.
Once both sockets are opened up and the plugin provider is ready to
be configured, it should emit `READY!` followed by a newline
on stdout.

In all cases, the following environment variables will be set when
the plugin provider is executed:

RS_ENDPOINT will be a URL to the usual dr-provision API endpoint
RS_TOKEN will be a long-lived token with superuser access rights
RS_FILESERVER will be a URL to the static file server
RS_WEBROOT will be the filesystem path to static file server space

The plugin provider will be executed with its current directory set
to a scratch directory it can use to hold temporary files.

Once the plugin provider is ready, its HTTP server should listen on the following paths:

POST /api-plugin/v4/config

When a JSON object containing the Params field from the Plugin object
this instance of the plugin provider is backing is POSTed to this API
endpoint, the plugin should configure itself accordingly.
This is the first call made into the plugin provider
when it starts, and it can be called any time afterwards.

POST /api-plugin/v4/stop

When this API endpoint is POSTed to, the plugin provider should cleanly
shut down.

POST /api-plugin/v4/action

When a JSON object containing a fully filled out models.Action is POSTed
to this API endpoint, the plugin provider should take the appropriate
action and return the results of the action.  This endpoint must be
able to handle all of the actions listed in the AvailableActions section
of the definition that the define command returned.

POST /api-plugin/v4/publish (DEPRECATED, use api.EventStream instead)

When a JSON object containing a fully filled out models.Event is POSTed
to this API endpoint, the plugin provider should handle the event as
appropriate.  Events will only be published to this endpoint if the
plugin provider definition HasPublish flag is true.

This endpoint is deprecated, as it is synchronous and can cause
performance bottlenecks and potentially deadlocks, along with not
being filterable on the server side.  Using an api.EventStream
is a better solution.

The HTTP client can POST back into dr-provision using the following paths on the client socket:

POST /api-plugin-server/v4/publish

The body should be a JSON serialized models.Event, which will be broadcast
to all interested parties.

POST /api-plugin-server/v4/leaving

This will cause dr-provision to cleanly shut down the plugin provider.
The body does not matter.

POST /api-plugin-server/v4/log

The body should be a JSON serialized logger.Line structure, which will be
added to the global dr-provision log.

Index

Package Files

interfaces.go plugin.go

Variables

var (

    // App is the global cobra command structure.
    App = &cobra.Command{
        Use:   "replaceme",
        Short: "Replace ME!",
    }
)

func InitApp Uses

func InitApp(use, short, version string, def *models.PluginProvider, pc PluginConfig)

InitApp initializes the plugin system and makes the base actions available in cobra CLI. It provides default implementations of the define, unpack, and listen commands, which will be backed by all the interfaces that whatever is passed in as pc satisfy.

func Leaving Uses

func Leaving(e *models.Error)

Leaving allows the plugin to inform DRP that it is about to exit.

func ListObjects Uses

func ListObjects(prefix string) ([]*models.RawModel, *models.Error)

func Publish Uses

func Publish(t, a, k string, o interface{})

Publish allows the plugin provider to generate events back to DRP.

type PluginActor Uses

type PluginActor interface {
    Action(logger.Logger, *models.Action) (interface{}, *models.Error)
}

PluginActor is an optional interface that your plugin should implement if you plan on handling Actions. If the PluginProvider definition has a non-empty list of AvailableActions, then the Action method must be available and able to handle all of the Actions in that list.

Action takes a logger and a fully-filled out Action, and returns the results of that action along with a non-nil models.Error if an error occurred while performing the action.

type PluginConfig Uses

type PluginConfig interface {
    Config(logger.Logger, *api.Client, map[string]interface{}) *models.Error
}

PluginConfig is a mandatory interface that your plugin must implement. Config will be called with the fully expanded Params on the plugin object whenever this instance of the Plugin is started or whenever those Params change.

Config takes three arguments: a logger, an API client with superuser rights, and a map of all the params on the Plugin being configured. It should return a non-nil models.Error if the Config call fails for any reason.

type PluginEventSelecter Uses

type PluginEventSelecter interface {
    SelectEvents() []string
}

PluginEventSelector is an optional interface that your plugin can implement to specify what events the plugin is interested in receiving from dr-provision. If this interface is implemented, then the HasPublish field in the PluginProvider definition must be false.

SelectEvents returns a slice of strings that define the events the Plugin wishes to receive.

type PluginPublisher Uses

type PluginPublisher interface {
    Publish(logger.Logger, *models.Event) *models.Error
}

PluginPublisher is an optional interface that your plugin can implement if it is interested in receiving events from dr-provision. There are a couple of things to be aware of when implementing a Publish method:

1. If you are implementing a Publish method, you should also implement a

SelectEvents method, and set the HasPublish flag on your PluginProvider
definition to false. This will allow dr-provision to only send you the
specific events you are interested in, and it will prevent your plugin
from being able to bottleneck (or even deadlock) dr-provision.

2. If you choose to not implement a SelectEvents method, the HasPublish

flag on your PluginProvider definition must be set to true, and your
Publish method will receive all the events dr-provision emits
synchronously.  It is therefore your responsibility handle taking action
on the events in such a way that you do not cause a deadlock or a
performance bottleneck.

Publish takes a logger and the event that was recieved, and returns a non-nil models.Error if there was an error handling the event.

type PluginStop Uses

type PluginStop interface {
    Stop(logger.Logger)
}

PluginStop is an optional interface that your plugin can implement to provide custom behaviour whenever the plugin is stopped. Stop will be called when a plugin needs to stop operating. If implement the PluginStop interface, it will be called before the default stop action takes place.

Stop takes one argument, a logger.

type PluginUnpacker Uses

type PluginUnpacker interface {
    Unpack(logger.Logger, string) error
}

PluginUnpacker is an optional interface that your plugin can implement if it needs to unpack additional assets into the static file space.

Unpack takes a logger and the location on the local filesystem any embedded assets should be unpacked into. It returns an error if there was a problem unpacking assets.

type PluginValidator Uses

type PluginValidator interface {
    Validate(logger.Logger, *api.Client) (interface{}, *models.Error)
}

PluginValidator is an optional interface that your plugin can implement if it needs to check that it can run in the environment it was executed in. Validate is a good method to implement to test for other executables, etc. that the Plugin may rely on to operate.

Validate takes a logger and an API client with superuser permissions, and returns the results of validating the environment and a non-nil models.Error if the plugin cannot be used in the current environment.

Directories

PathSynopsis
mux

Package plugin imports 14 packages (graph). Updated 2019-12-05. Refresh now. Tools for package owners.