Plugins: Transform plugin support (#20036)

currently temporary separate http api
This commit is contained in:
Kyle Brandt
2019-10-29 12:22:31 -04:00
committed by GitHub
parent 69691fbd6e
commit 009d58c4a2
32 changed files with 2022 additions and 1187 deletions

View File

@ -0,0 +1,81 @@
package backendplugin
import (
"os/exec"
"github.com/grafana/grafana/pkg/infra/log"
datasourceV1 "github.com/grafana/grafana-plugin-model/go/datasource"
rendererV1 "github.com/grafana/grafana-plugin-model/go/renderer"
sdk "github.com/grafana/grafana-plugin-sdk-go/common"
datasourceV2 "github.com/grafana/grafana-plugin-sdk-go/datasource"
transformV2 "github.com/grafana/grafana-plugin-sdk-go/transform"
"github.com/hashicorp/go-plugin"
)
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.
var handshake = plugin.HandshakeConfig{
// 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.
MagicCookieKey: sdk.MagicCookieKey,
MagicCookieValue: sdk.MagicCookieValue,
}
// NewClientConfig returns a configuration object that can be used to instantiate
// a client for the plugin described by the given metadata.
func NewClientConfig(executablePath string, logger log.Logger, versionedPlugins map[int]plugin.PluginSet) *plugin.ClientConfig {
return &plugin.ClientConfig{
Cmd: exec.Command(executablePath),
HandshakeConfig: handshake,
VersionedPlugins: versionedPlugins,
Logger: logWrapper{Logger: logger},
AllowedProtocols: []plugin.Protocol{plugin.ProtocolGRPC},
}
}
// NewDatasourceClient returns a datasource plugin client.
func NewDatasourceClient(pluginID, executablePath string, logger log.Logger) *plugin.Client {
versionedPlugins := map[int]plugin.PluginSet{
1: {
pluginID: &datasourceV1.DatasourcePluginImpl{},
},
2: {
pluginID: &datasourceV2.DatasourcePluginImpl{},
},
}
return plugin.NewClient(NewClientConfig(executablePath, logger, versionedPlugins))
}
// NewRendererClient returns a renderer plugin client.
func NewRendererClient(pluginID, executablePath string, logger log.Logger) *plugin.Client {
versionedPlugins := map[int]plugin.PluginSet{
1: {
pluginID: &rendererV1.RendererPluginImpl{},
},
}
return plugin.NewClient(NewClientConfig(executablePath, logger, versionedPlugins))
}
// NewTransformClient returns a transform plugin client.
func NewTransformClient(pluginID, executablePath string, logger log.Logger) *plugin.Client {
versionedPlugins := map[int]plugin.PluginSet{
2: {
pluginID: &transformV2.TransformPluginImpl{},
},
}
return plugin.NewClient(NewClientConfig(executablePath, logger, versionedPlugins))
}

View File

@ -0,0 +1,58 @@
package backendplugin
import (
"io"
"io/ioutil"
"log"
glog "github.com/grafana/grafana/pkg/infra/log"
hclog "github.com/hashicorp/go-hclog"
)
type logWrapper struct {
Logger glog.Logger
}
func (lw logWrapper) Trace(msg string, args ...interface{}) {
lw.Logger.Debug(msg, args...)
}
func (lw logWrapper) Debug(msg string, args ...interface{}) {
lw.Logger.Debug(msg, args...)
}
func (lw logWrapper) Info(msg string, args ...interface{}) {
lw.Logger.Info(msg, args...)
}
func (lw logWrapper) Warn(msg string, args ...interface{}) {
lw.Logger.Warn(msg, args...)
}
func (lw logWrapper) Error(msg string, args ...interface{}) {
lw.Logger.Error(msg, args...)
}
func (lw logWrapper) IsTrace() bool { return true }
func (lw logWrapper) IsDebug() bool { return true }
func (lw logWrapper) IsInfo() bool { return true }
func (lw logWrapper) IsWarn() bool { return true }
func (lw logWrapper) IsError() bool { return true }
func (lw logWrapper) With(args ...interface{}) hclog.Logger {
return logWrapper{Logger: lw.Logger.New(args...)}
}
func (lw logWrapper) Named(name string) hclog.Logger {
return logWrapper{Logger: lw.Logger.New()}
}
func (lw logWrapper) ResetNamed(name string) hclog.Logger {
return logWrapper{Logger: lw.Logger.New()}
}
func (lw logWrapper) StandardLogger(ops *hclog.StandardLoggerOptions) *log.Logger {
return nil
}
func (lw logWrapper) SetLevel(level hclog.Level) {}
// Return a value that conforms to io.Writer, which can be passed into log.SetOutput()
func (lw logWrapper) StandardWriter(opts *hclog.StandardLoggerOptions) io.Writer {
return ioutil.Discard
}