mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-17 03:57:01 +02:00
Add plugin version to GRPC interface Added a version interface in the sdk/logical so that it can be shared between all plugin types, and then wired it up to RunningVersion in the mounts, auth list, and database systems. I've tested that this works with auth, database, and secrets plugin types, with the following logic to populate RunningVersion: If a plugin has a PluginVersion() method implemented, then that is used If not, and the plugin is built into the Vault binary, then the go.mod version is used Otherwise, the it will be the empty string. My apologies for the length of this PR. * Placeholder backend should be external We use a placeholder backend (previously a framework.Backend) before a GRPC plugin is lazy-loaded. This makes us later think the plugin is a builtin plugin. So we added a `placeholderBackend` type that overrides the `IsExternal()` method so that later we know that the plugin is external, and don't give it a default builtin version.
70 lines
2.0 KiB
Go
70 lines
2.0 KiB
Go
package dbplugin
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/hashicorp/go-plugin"
|
|
"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto"
|
|
"github.com/hashicorp/vault/sdk/helper/pluginutil"
|
|
"github.com/hashicorp/vault/sdk/logical"
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
// handshakeConfigs are used to just do a basic handshake between
|
|
// a plugin and host. If the handshake fails, a user friendly error is shown.
|
|
// This prevents users from executing bad plugins or executing a plugin
|
|
// directory. It is a UX feature, not a security feature.
|
|
var HandshakeConfig = plugin.HandshakeConfig{
|
|
MagicCookieKey: "VAULT_DATABASE_PLUGIN",
|
|
MagicCookieValue: "926a0820-aea2-be28-51d6-83cdf00e8edb",
|
|
}
|
|
|
|
// Factory is the factory function to create a dbplugin Database.
|
|
type Factory func() (interface{}, error)
|
|
|
|
type GRPCDatabasePlugin struct {
|
|
FactoryFunc Factory
|
|
Impl Database
|
|
|
|
// Embeding this will disable the netRPC protocol
|
|
plugin.NetRPCUnsupportedPlugin
|
|
}
|
|
|
|
var (
|
|
_ plugin.Plugin = &GRPCDatabasePlugin{}
|
|
_ plugin.GRPCPlugin = &GRPCDatabasePlugin{}
|
|
)
|
|
|
|
func (d GRPCDatabasePlugin) GRPCServer(_ *plugin.GRPCBroker, s *grpc.Server) error {
|
|
var server gRPCServer
|
|
|
|
if d.Impl != nil {
|
|
server = gRPCServer{singleImpl: d.Impl}
|
|
} else {
|
|
// multiplexing is supported
|
|
server = gRPCServer{
|
|
factoryFunc: d.FactoryFunc,
|
|
instances: make(map[string]Database),
|
|
}
|
|
|
|
// Multiplexing is enabled for this plugin, register the server so we
|
|
// can tell the client in Vault.
|
|
pluginutil.RegisterPluginMultiplexingServer(s, pluginutil.PluginMultiplexingServerImpl{
|
|
Supported: true,
|
|
})
|
|
}
|
|
|
|
proto.RegisterDatabaseServer(s, &server)
|
|
logical.RegisterPluginVersionServer(s, &server)
|
|
return nil
|
|
}
|
|
|
|
func (GRPCDatabasePlugin) GRPCClient(doneCtx context.Context, _ *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {
|
|
client := gRPCClient{
|
|
client: proto.NewDatabaseClient(c),
|
|
versionClient: logical.NewPluginVersionClient(c),
|
|
doneCtx: doneCtx,
|
|
}
|
|
return client, nil
|
|
}
|