Skip to content

Commit

Permalink
refactor database plugin sdk and prepare for ent database plugin sdk …
Browse files Browse the repository at this point in the history
…development
  • Loading branch information
thyton committed Jan 31, 2025
1 parent cda9ad3 commit e9b3ac4
Show file tree
Hide file tree
Showing 15 changed files with 266 additions and 164 deletions.
16 changes: 2 additions & 14 deletions sdk/database/dbplugin/v5/grpc_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"time"

"github.com/golang/protobuf/ptypes"

"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto"
"github.com/hashicorp/vault/sdk/helper/pluginutil"
"github.com/hashicorp/vault/sdk/logical"
Expand All @@ -25,6 +26,7 @@ var (
)

type gRPCClient struct {
entGRPCClient
client proto.DatabaseClient
versionClient logical.PluginVersionClient
doneCtx context.Context
Expand Down Expand Up @@ -285,20 +287,6 @@ func (c gRPCClient) Type() (string, error) {
return typeResp.GetType(), nil
}

func (c gRPCClient) Close() error {
ctx, cancel := getContextWithTimeout(pluginutil.PluginGRPCTimeoutClose)
defer cancel()

_, err := c.client.Close(ctx, &proto.Empty{})
if err != nil {
if c.doneCtx.Err() != nil {
return ErrPluginShutdown
}
return err
}
return nil
}

func getContextWithTimeout(env string) (context.Context, context.CancelFunc) {
timeout := 1 // default timeout
if envTimeout, err := strconv.Atoi(os.Getenv(env)); err == nil && envTimeout > 0 {
Expand Down
27 changes: 27 additions & 0 deletions sdk/database/dbplugin/v5/grpc_client_stubs_oss.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

//go:build !enterprise

package dbplugin

import (
"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto"
"github.com/hashicorp/vault/sdk/helper/pluginutil"
)

type entGRPCClient struct{}

func (c gRPCClient) Close() error {
ctx, cancel := getContextWithTimeout(pluginutil.PluginGRPCTimeoutClose)
defer cancel()

_, err := c.client.Close(ctx, &proto.Empty{})
if err != nil {
if c.doneCtx.Err() != nil {
return ErrPluginShutdown
}
return err
}
return nil
}
31 changes: 31 additions & 0 deletions sdk/database/dbplugin/v5/grpc_client_stubs_oss_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

//go:build !enterprise

package dbplugin

import (
"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto"
)

var _ proto.DatabaseClient = fakeClient{}

type fakeClient struct {
initResp *proto.InitializeResponse
initErr error

newUserResp *proto.NewUserResponse
newUserErr error

updateUserResp *proto.UpdateUserResponse
updateUserErr error

deleteUserResp *proto.DeleteUserResponse
deleteUserErr error

typeResp *proto.TypeResponse
typeErr error

closeErr error
}
21 changes: 1 addition & 20 deletions sdk/database/dbplugin/v5/grpc_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,26 +518,7 @@ func assertErrEquals(expectedErr error) errorAssertion {
}
}

var _ proto.DatabaseClient = fakeClient{}

type fakeClient struct {
initResp *proto.InitializeResponse
initErr error

newUserResp *proto.NewUserResponse
newUserErr error

updateUserResp *proto.UpdateUserResponse
updateUserErr error

deleteUserResp *proto.DeleteUserResponse
deleteUserErr error

typeResp *proto.TypeResponse
typeErr error

closeErr error
}
// fakeClient methods

func (f fakeClient) Initialize(context.Context, *proto.InitializeRequest, ...grpc.CallOption) (*proto.InitializeResponse, error) {
return f.initResp, f.initErr
Expand Down
39 changes: 0 additions & 39 deletions sdk/database/dbplugin/v5/grpc_database_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,7 @@
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
Expand All @@ -37,36 +31,3 @@ 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
}
55 changes: 55 additions & 0 deletions sdk/database/dbplugin/v5/grpc_database_plugin_stubs_oss.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

//go:build !enterprise

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"
)

// GRPCClient (Vault CE edition) initializes and returns a gRPCClient with Database and
// PluginVersion gRPC clients. It implements GRPCClient() defined
// by GRPCPlugin interface in go-plugin/plugin.go
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
}

// GRPCServer (Vault CE edition) registers multiplexing server if the plugin supports it, and
// registers the Database and PluginVersion gRPC servers. It implements GRPCServer() defined
// by GRPCPlugin interface in go-plugin/plugin.go
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
}
16 changes: 0 additions & 16 deletions sdk/database/dbplugin/v5/grpc_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"context"
"errors"
"fmt"
"sync"
"time"

"github.com/golang/protobuf/ptypes"
Expand All @@ -21,21 +20,6 @@ import (

var _ proto.DatabaseServer = &gRPCServer{}

type gRPCServer struct {
proto.UnimplementedDatabaseServer
logical.UnimplementedPluginVersionServer

// holds the non-multiplexed Database
// when this is set the plugin does not support multiplexing
singleImpl Database

// instances holds the multiplexed Databases
instances map[string]Database
factoryFunc func() (interface{}, error)

sync.RWMutex
}

func (g *gRPCServer) getOrCreateDatabase(ctx context.Context) (Database, error) {
g.Lock()
defer g.Unlock()
Expand Down
28 changes: 28 additions & 0 deletions sdk/database/dbplugin/v5/grpc_server_stubs_oss.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

//go:build !enterprise

package dbplugin

import (
"sync"

"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto"
"github.com/hashicorp/vault/sdk/logical"
)

type gRPCServer struct {
proto.UnimplementedDatabaseServer
logical.UnimplementedPluginVersionServer

// holds the non-multiplexed Database
// when this is set the plugin does not support multiplexing
singleImpl Database

// instances holds the multiplexed Databases
instances map[string]Database
factoryFunc func() (interface{}, error)

sync.RWMutex
}
54 changes: 54 additions & 0 deletions sdk/database/dbplugin/v5/grpc_server_stubs_oss_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

//go:build !enterprise

package dbplugin

import (
"github.com/hashicorp/vault/sdk/logical"
)

var _ Database = fakeDatabase{}

type fakeDatabase struct {
initResp InitializeResponse
initErr error

newUserResp NewUserResponse
newUserErr error

updateUserResp UpdateUserResponse
updateUserErr error

deleteUserResp DeleteUserResponse
deleteUserErr error

typeResp string
typeErr error

closeErr error
}

var _ Database = &recordingDatabase{}

type recordingDatabase struct {
initializeCalls int
newUserCalls int
updateUserCalls int
deleteUserCalls int
typeCalls int
closeCalls int

// recordingDatabase can act as middleware so we can record the calls to other test Database implementations
next Database
}

type fakeDatabaseWithVersion struct {
version string
}

var (
_ Database = (*fakeDatabaseWithVersion)(nil)
_ logical.PluginVersioner = (*fakeDatabaseWithVersion)(nil)
)
Loading

0 comments on commit e9b3ac4

Please sign in to comment.