mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
131 lines
5.1 KiB
Go
131 lines
5.1 KiB
Go
package grpcplugin
|
|
|
|
import (
|
|
"os/exec"
|
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend/grpcplugin"
|
|
grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
|
|
goplugin "github.com/hashicorp/go-plugin"
|
|
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
|
"google.golang.org/grpc"
|
|
|
|
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
|
"github.com/grafana/grafana/pkg/plugins/backendplugin/pluginextensionv2"
|
|
"github.com/grafana/grafana/pkg/plugins/backendplugin/secretsmanagerplugin"
|
|
"github.com/grafana/grafana/pkg/plugins/log"
|
|
)
|
|
|
|
// Handshake is the HandshakeConfig used to configure clients and servers.
|
|
var handshake = goplugin.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: grpcplugin.ProtocolVersion,
|
|
|
|
// The magic cookie values should NEVER be changed.
|
|
MagicCookieKey: grpcplugin.MagicCookieKey,
|
|
MagicCookieValue: grpcplugin.MagicCookieValue,
|
|
}
|
|
|
|
func newClientConfig(executablePath string, env []string, logger log.Logger,
|
|
versionedPlugins map[int]goplugin.PluginSet) *goplugin.ClientConfig {
|
|
// We can ignore gosec G201 here, since the dynamic part of executablePath comes from the plugin definition
|
|
// nolint:gosec
|
|
cmd := exec.Command(executablePath)
|
|
cmd.Env = env
|
|
|
|
return &goplugin.ClientConfig{
|
|
Cmd: cmd,
|
|
HandshakeConfig: handshake,
|
|
VersionedPlugins: versionedPlugins,
|
|
Logger: logWrapper{Logger: logger},
|
|
AllowedProtocols: []goplugin.Protocol{goplugin.ProtocolGRPC},
|
|
GRPCDialOptions: []grpc.DialOption{
|
|
grpc.WithChainUnaryInterceptor(
|
|
otelgrpc.UnaryClientInterceptor(),
|
|
grpc_opentracing.UnaryClientInterceptor(),
|
|
),
|
|
grpc.WithChainStreamInterceptor(
|
|
otelgrpc.StreamClientInterceptor(),
|
|
grpc_opentracing.StreamClientInterceptor(),
|
|
),
|
|
},
|
|
}
|
|
}
|
|
|
|
// StartRendererFunc callback function called when a renderer plugin is started.
|
|
type StartRendererFunc func(pluginID string, renderer pluginextensionv2.RendererPlugin, logger log.Logger) error
|
|
|
|
// StartSecretsManagerFunc callback function called when a secrets manager plugin is started.
|
|
type StartSecretsManagerFunc func(pluginID string, secretsmanager secretsmanagerplugin.SecretsManagerPlugin, logger log.Logger) error
|
|
|
|
// PluginDescriptor is a descriptor used for registering backend plugins.
|
|
type PluginDescriptor struct {
|
|
pluginID string
|
|
executablePath string
|
|
managed bool
|
|
versionedPlugins map[int]goplugin.PluginSet
|
|
startRendererFn StartRendererFunc
|
|
startSecretsManagerFn StartSecretsManagerFunc
|
|
}
|
|
|
|
// getV2PluginSet returns list of plugins supported on v2.
|
|
func getV2PluginSet() goplugin.PluginSet {
|
|
return goplugin.PluginSet{
|
|
"diagnostics": &grpcplugin.DiagnosticsGRPCPlugin{},
|
|
"resource": &grpcplugin.ResourceGRPCPlugin{},
|
|
"data": &grpcplugin.DataGRPCPlugin{},
|
|
"stream": &grpcplugin.StreamGRPCPlugin{},
|
|
"renderer": &pluginextensionv2.RendererGRPCPlugin{},
|
|
"secretsmanager": &secretsmanagerplugin.SecretsManagerGRPCPlugin{},
|
|
}
|
|
}
|
|
|
|
// NewBackendPlugin creates a new backend plugin factory used for registering a backend plugin.
|
|
func NewBackendPlugin(pluginID, executablePath string) backendplugin.PluginFactoryFunc {
|
|
return newBackendPlugin(pluginID, executablePath, true)
|
|
}
|
|
|
|
// NewUnmanagedBackendPlugin creates a new backend plugin factory used for registering an unmanaged backend plugin.
|
|
func NewUnmanagedBackendPlugin(pluginID, executablePath string) backendplugin.PluginFactoryFunc {
|
|
return newBackendPlugin(pluginID, executablePath, false)
|
|
}
|
|
|
|
// NewBackendPlugin creates a new backend plugin factory used for registering a backend plugin.
|
|
func newBackendPlugin(pluginID, executablePath string, managed bool) backendplugin.PluginFactoryFunc {
|
|
return newPlugin(PluginDescriptor{
|
|
pluginID: pluginID,
|
|
executablePath: executablePath,
|
|
managed: managed,
|
|
versionedPlugins: map[int]goplugin.PluginSet{
|
|
grpcplugin.ProtocolVersion: getV2PluginSet(),
|
|
},
|
|
})
|
|
}
|
|
|
|
// NewRendererPlugin creates a new renderer plugin factory used for registering a backend renderer plugin.
|
|
func NewRendererPlugin(pluginID, executablePath string, startFn StartRendererFunc) backendplugin.PluginFactoryFunc {
|
|
return newPlugin(PluginDescriptor{
|
|
pluginID: pluginID,
|
|
executablePath: executablePath,
|
|
managed: false,
|
|
versionedPlugins: map[int]goplugin.PluginSet{
|
|
grpcplugin.ProtocolVersion: getV2PluginSet(),
|
|
},
|
|
startRendererFn: startFn,
|
|
})
|
|
}
|
|
|
|
// NewSecetsManagerPlugin creates a new secrets manager plugin factory used for registering a backend secrets manager plugin.
|
|
func NewSecretsManagerPlugin(pluginID, executablePath string, startFn StartSecretsManagerFunc) backendplugin.PluginFactoryFunc {
|
|
return newPlugin(PluginDescriptor{
|
|
pluginID: pluginID,
|
|
executablePath: executablePath,
|
|
managed: false,
|
|
versionedPlugins: map[int]goplugin.PluginSet{
|
|
grpcplugin.ProtocolVersion: getV2PluginSet(),
|
|
},
|
|
startSecretsManagerFn: startFn,
|
|
})
|
|
}
|