github.com/hashicorp/vault/sdk@v0.13.0/database/dbplugin/v5/plugin_client.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package dbplugin 5 6 import ( 7 "context" 8 "errors" 9 10 "github.com/hashicorp/go-plugin" 11 "github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" 12 "github.com/hashicorp/vault/sdk/helper/pluginutil" 13 "github.com/hashicorp/vault/sdk/logical" 14 ) 15 16 var _ logical.PluginVersioner = (*DatabasePluginClient)(nil) 17 18 type DatabasePluginClient struct { 19 client pluginutil.PluginClient 20 Database 21 } 22 23 func (dc *DatabasePluginClient) PluginVersion() logical.PluginVersion { 24 if versioner, ok := dc.Database.(logical.PluginVersioner); ok { 25 return versioner.PluginVersion() 26 } 27 return logical.EmptyPluginVersion 28 } 29 30 // This wraps the Close call and ensures we both close the database connection 31 // and kill the plugin. 32 func (dc *DatabasePluginClient) Close() error { 33 err := dc.Database.Close() 34 dc.client.Close() 35 36 return err 37 } 38 39 // pluginSets is the map of plugins we can dispense. 40 var PluginSets = map[int]plugin.PluginSet{ 41 5: { 42 "database": &GRPCDatabasePlugin{}, 43 }, 44 6: { 45 "database": &GRPCDatabasePlugin{}, 46 }, 47 } 48 49 // NewPluginClient returns a databaseRPCClient with a connection to a running 50 // plugin. 51 func NewPluginClient(ctx context.Context, sys pluginutil.RunnerUtil, config pluginutil.PluginClientConfig) (Database, error) { 52 pluginClient, err := sys.NewPluginClient(ctx, config) 53 if err != nil { 54 return nil, err 55 } 56 57 // Request the plugin 58 raw, err := pluginClient.Dispense("database") 59 if err != nil { 60 return nil, err 61 } 62 63 // We should have a database type now. This feels like a normal interface 64 // implementation but is in fact over an RPC connection. 65 var db Database 66 switch c := raw.(type) { 67 case gRPCClient: 68 // This is an abstraction leak from go-plugin but it is necessary in 69 // order to enable multiplexing on multiplexed plugins 70 c.client = proto.NewDatabaseClient(pluginClient.Conn()) 71 c.versionClient = logical.NewPluginVersionClient(pluginClient.Conn()) 72 73 db = c 74 default: 75 return nil, errors.New("unsupported client type") 76 } 77 78 return &DatabasePluginClient{ 79 client: pluginClient, 80 Database: db, 81 }, nil 82 }