2020-06-11 09:14:05 -05:00
|
|
|
package grpcplugin
|
2019-10-29 11:22:31 -05:00
|
|
|
|
|
|
|
import (
|
|
|
|
"os/exec"
|
|
|
|
|
|
|
|
datasourceV1 "github.com/grafana/grafana-plugin-model/go/datasource"
|
|
|
|
rendererV1 "github.com/grafana/grafana-plugin-model/go/renderer"
|
2020-04-21 09:16:41 -05:00
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend/grpcplugin"
|
2020-06-11 09:14:05 -05:00
|
|
|
sdkgrpcplugin "github.com/grafana/grafana-plugin-sdk-go/backend/grpcplugin"
|
2020-04-21 09:16:41 -05:00
|
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
2020-06-11 09:14:05 -05:00
|
|
|
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
2020-04-21 09:16:41 -05:00
|
|
|
"github.com/grafana/grafana/pkg/plugins/backendplugin/pluginextensionv2"
|
2020-01-31 04:15:50 -06:00
|
|
|
goplugin "github.com/hashicorp/go-plugin"
|
2019-10-29 11:22:31 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// DefaultProtocolVersion is the protocol version assumed for legacy clients that don't specify
|
|
|
|
// a particular version or version 1 during their handshake. This is currently the version used
|
|
|
|
// since Grafana launched support for backend plugins.
|
|
|
|
DefaultProtocolVersion = 1
|
|
|
|
)
|
|
|
|
|
|
|
|
// Handshake is the HandshakeConfig used to configure clients and servers.
|
2020-01-31 04:15:50 -06:00
|
|
|
var handshake = goplugin.HandshakeConfig{
|
2019-10-29 11:22:31 -05:00
|
|
|
// The ProtocolVersion is the version that must match between Grafana core
|
|
|
|
// and Grafana plugins. This should be bumped whenever a (breaking) change
|
|
|
|
// happens in one or the other that makes it so that they can't safely communicate.
|
|
|
|
ProtocolVersion: DefaultProtocolVersion,
|
|
|
|
|
|
|
|
// The magic cookie values should NEVER be changed.
|
2020-06-11 09:14:05 -05:00
|
|
|
MagicCookieKey: sdkgrpcplugin.MagicCookieKey,
|
|
|
|
MagicCookieValue: sdkgrpcplugin.MagicCookieValue,
|
2019-10-29 11:22:31 -05:00
|
|
|
}
|
|
|
|
|
2020-04-14 11:04:27 -05:00
|
|
|
func newClientConfig(executablePath string, env []string, logger log.Logger, versionedPlugins map[int]goplugin.PluginSet) *goplugin.ClientConfig {
|
|
|
|
cmd := exec.Command(executablePath)
|
|
|
|
cmd.Env = env
|
|
|
|
|
2020-01-31 04:15:50 -06:00
|
|
|
return &goplugin.ClientConfig{
|
2020-04-14 11:04:27 -05:00
|
|
|
Cmd: cmd,
|
2019-10-29 11:22:31 -05:00
|
|
|
HandshakeConfig: handshake,
|
|
|
|
VersionedPlugins: versionedPlugins,
|
|
|
|
Logger: logWrapper{Logger: logger},
|
2020-01-31 04:15:50 -06:00
|
|
|
AllowedProtocols: []goplugin.Protocol{goplugin.ProtocolGRPC},
|
2019-10-29 11:22:31 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-13 10:13:17 -06:00
|
|
|
// LegacyStartFunc callback function called when a plugin with old plugin protocol is started.
|
|
|
|
type LegacyStartFunc func(pluginID string, client *LegacyClient, logger log.Logger) error
|
|
|
|
|
|
|
|
// StartFunc callback function called when a plugin with current plugin protocol version is started.
|
|
|
|
type StartFunc func(pluginID string, client *Client, logger log.Logger) error
|
|
|
|
|
|
|
|
// PluginStartFuncs functions called for plugin when started.
|
|
|
|
type PluginStartFuncs struct {
|
|
|
|
OnLegacyStart LegacyStartFunc
|
|
|
|
OnStart StartFunc
|
|
|
|
}
|
|
|
|
|
2020-05-12 08:48:24 -05:00
|
|
|
// PluginDescriptor is a descriptor used for registering backend plugins.
|
2020-01-08 10:43:28 -06:00
|
|
|
type PluginDescriptor struct {
|
|
|
|
pluginID string
|
|
|
|
executablePath string
|
|
|
|
managed bool
|
2020-01-31 04:15:50 -06:00
|
|
|
versionedPlugins map[int]goplugin.PluginSet
|
2020-01-13 10:13:17 -06:00
|
|
|
startFns PluginStartFuncs
|
2019-10-29 11:22:31 -05:00
|
|
|
}
|
|
|
|
|
2020-04-21 09:16:41 -05:00
|
|
|
// getV2PluginSet returns list of plugins supported on v2.
|
|
|
|
func getV2PluginSet() goplugin.PluginSet {
|
|
|
|
return goplugin.PluginSet{
|
2020-06-11 09:14:05 -05:00
|
|
|
"diagnostics": &sdkgrpcplugin.DiagnosticsGRPCPlugin{},
|
|
|
|
"resource": &sdkgrpcplugin.ResourceGRPCPlugin{},
|
|
|
|
"data": &sdkgrpcplugin.DataGRPCPlugin{},
|
|
|
|
"transform": &sdkgrpcplugin.TransformGRPCPlugin{},
|
2020-04-21 09:16:41 -05:00
|
|
|
"renderer": &pluginextensionv2.RendererGRPCPlugin{},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 09:14:05 -05:00
|
|
|
// NewBackendPlugin creates a new backend plugin factory used for registering a backend plugin.
|
|
|
|
func NewBackendPlugin(pluginID, executablePath string, startFns PluginStartFuncs) backendplugin.PluginFactoryFunc {
|
|
|
|
return New(PluginDescriptor{
|
2020-01-08 10:43:28 -06:00
|
|
|
pluginID: pluginID,
|
|
|
|
executablePath: executablePath,
|
|
|
|
managed: true,
|
2020-01-31 04:15:50 -06:00
|
|
|
versionedPlugins: map[int]goplugin.PluginSet{
|
2020-01-08 10:43:28 -06:00
|
|
|
DefaultProtocolVersion: {
|
|
|
|
pluginID: &datasourceV1.DatasourcePluginImpl{},
|
|
|
|
},
|
2020-06-11 09:14:05 -05:00
|
|
|
sdkgrpcplugin.ProtocolVersion: getV2PluginSet(),
|
2019-10-29 11:22:31 -05:00
|
|
|
},
|
2020-01-13 10:13:17 -06:00
|
|
|
startFns: startFns,
|
2020-06-11 09:14:05 -05:00
|
|
|
})
|
2019-10-29 11:22:31 -05:00
|
|
|
}
|
|
|
|
|
2020-06-11 09:14:05 -05:00
|
|
|
// NewRendererPlugin creates a new renderer plugin factory used for registering a backend renderer plugin.
|
|
|
|
func NewRendererPlugin(pluginID, executablePath string, startFns PluginStartFuncs) backendplugin.PluginFactoryFunc {
|
|
|
|
return New(PluginDescriptor{
|
2020-01-08 10:43:28 -06:00
|
|
|
pluginID: pluginID,
|
|
|
|
executablePath: executablePath,
|
|
|
|
managed: false,
|
2020-01-31 04:15:50 -06:00
|
|
|
versionedPlugins: map[int]goplugin.PluginSet{
|
2020-01-08 10:43:28 -06:00
|
|
|
DefaultProtocolVersion: {
|
|
|
|
pluginID: &rendererV1.RendererPluginImpl{},
|
|
|
|
},
|
2020-06-11 09:14:05 -05:00
|
|
|
sdkgrpcplugin.ProtocolVersion: getV2PluginSet(),
|
2019-10-29 11:22:31 -05:00
|
|
|
},
|
2020-01-13 10:13:17 -06:00
|
|
|
startFns: startFns,
|
2020-06-11 09:14:05 -05:00
|
|
|
})
|
2020-01-31 04:15:50 -06:00
|
|
|
}
|
|
|
|
|
2020-06-11 09:14:05 -05:00
|
|
|
// LegacyClient client for communicating with a plugin using the v1 plugin protocol.
|
2020-01-13 10:13:17 -06:00
|
|
|
type LegacyClient struct {
|
|
|
|
DatasourcePlugin datasourceV1.DatasourcePlugin
|
|
|
|
RendererPlugin rendererV1.RendererPlugin
|
|
|
|
}
|
|
|
|
|
2020-06-11 09:14:05 -05:00
|
|
|
// Client client for communicating with a plugin using the current (v2) plugin protocol.
|
2020-01-13 10:13:17 -06:00
|
|
|
type Client struct {
|
2020-06-11 09:14:05 -05:00
|
|
|
DataPlugin grpcplugin.DataClient
|
|
|
|
TransformPlugin grpcplugin.TransformClient
|
2020-04-21 09:16:41 -05:00
|
|
|
RendererPlugin pluginextensionv2.RendererPlugin
|
2020-01-13 10:13:17 -06:00
|
|
|
}
|