From bd92933d922260d7e6cc2009042a3d7dd6691109 Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Tue, 28 Nov 2017 23:22:28 -0800 Subject: [PATCH 1/9] Start work on context aware backends --- logical/plugin/backend_client.go | 45 ++++++++++-- logical/plugin/backend_server.go | 17 +++++ logical/plugin/context.go | 119 +++++++++++++++++++++++++++++++ logical/request.go | 5 ++ vault/request_handling.go | 5 ++ 5 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 logical/plugin/context.go diff --git a/logical/plugin/backend_client.go b/logical/plugin/backend_client.go index 960e28696d52..5864a9c3e108 100644 --- a/logical/plugin/backend_client.go +++ b/logical/plugin/backend_client.go @@ -26,8 +26,10 @@ type backendPluginClient struct { // HandleRequestArgs is the args for HandleRequest method. type HandleRequestArgs struct { - StorageID uint32 - Request *logical.Request + StorageID uint32 + Request *logical.Request + ContextCancelID uint32 + ContextID uint32 } // HandleRequestReply is the reply for HandleRequest method. @@ -96,8 +98,20 @@ func (b *backendPluginClient) HandleRequest(req *logical.Request) (*logical.Resp // Do not send the storage, since go-plugin cannot serialize // interfaces. The server will pick up the storage from the shim. req.Storage = nil + + contextID := b.broker.NextId() + go b.broker.AcceptAndServe(contextID, &ContextServer{ + ctx: req.Context, + }) + + ctx := req.Context + req.Context = nil + cancelID := b.broker.NextId() + args := &HandleRequestArgs{ - Request: req, + Request: req, + ContextID: contextID, + ContextCancelID: cancelID, } var reply HandleRequestReply @@ -109,7 +123,30 @@ func (b *backendPluginClient) HandleRequest(req *logical.Request) (*logical.Resp }() } - err := b.client.Call("Plugin.HandleRequest", args, &reply) + c := make(chan error) + quit := make(chan struct{}) + go func() { + c <- b.client.Call("Plugin.HandleRequest", args, &reply) + }() + + ctxConn, err := b.broker.Dial(cancelID) + if err != nil { + return nil, err + } + defer ctxConn.Close() + ctxClient := rpc.NewClient(ctxConn) + + canceler := &ContextCancelClient{client: ctxClient} + go func() { + select { + case <-ctx.Done(): + canceler.Cancel() + case <-quit: + } + }() + + err = <-c + close(quit) if err != nil { return nil, err } diff --git a/logical/plugin/backend_server.go b/logical/plugin/backend_server.go index eb490fb24e56..cb6431358bc5 100644 --- a/logical/plugin/backend_server.go +++ b/logical/plugin/backend_server.go @@ -35,6 +35,23 @@ func (b *backendPluginServer) HandleRequest(args *HandleRequestArgs, reply *Hand return ErrServerInMetadataMode } + ctxConn, err := b.broker.Dial(args.ContextID) + if err != nil { + *reply = HandleRequestReply{ + Error: wrapError(err), + } + return nil + } + ctxClient := rpc.NewClient(ctxConn) + + ctx := &ContextClient{client: ctxClient} + + go b.broker.AcceptAndServe(args.ContextCancelID, &ContextCancelServer{ + ctx.CancelFunc(), + }) + + args.Request.Context = ctx + storage := &StorageClient{client: b.storageClient} args.Request.Storage = storage diff --git a/logical/plugin/context.go b/logical/plugin/context.go new file mode 100644 index 000000000000..5c670c1ec597 --- /dev/null +++ b/logical/plugin/context.go @@ -0,0 +1,119 @@ +package plugin + +import ( + "context" + "net/rpc" + "time" +) + +type ContextCancelClient struct { + client *rpc.Client +} + +func (c *ContextCancelClient) Cancel() { + c.client.Call("Plugin.ContextCancel", struct{}{}, struct{}{}) +} + +type ContextCancelServer struct { + f context.CancelFunc +} + +func (c ContextCancelServer) ContextCancel(_ struct{}, _ struct{}) { + c.f() +} + +// StorageClient is an implementation of logical.Storage that communicates +// over RPC. +type ContextClient struct { + client *rpc.Client + d chan struct{} + cachedErr error +} + +func (c *ContextClient) CancelFunc() context.CancelFunc { + return func() { close(c.d) } +} + +func (c *ContextClient) Deadline() (deadline time.Time, ok bool) { + var reply ContextDeadlineReply + err := c.client.Call("Plugin.Deadline", struct{}{}, &reply) + if err != nil { + return time.Time{}, false + } + + return reply.Deadline, reply.Ok +} +func (c *ContextClient) Done() <-chan struct{} { + return c.d +} + +func (c *ContextClient) Err() error { + if c.cachedErr != nil { + return c.cachedErr + } + + var reply ContextErrReply + err := c.client.Call("Plugin.Err", struct{}{}, &reply) + if err != nil { + return err + } + + if reply.Err != nil { + c.cachedErr = reply.Err + } + + return reply.Err +} + +func (c *ContextClient) Value(key interface{}) interface{} { + var reply ContextValueReply + err := c.client.Call("Plugin.Value", key, &reply) + if err != nil { + return nil + } + + return reply.Value +} + +// StorageServer is a net/rpc compatible structure for serving +type ContextServer struct { + ctx context.Context +} + +func (c *ContextServer) Deadline(_ struct{}, reply *ContextDeadlineReply) error { + d, ok := c.ctx.Deadline() + *reply = ContextDeadlineReply{ + Deadline: d, + Ok: ok, + } + return nil +} + +func (c *ContextServer) Err(_ struct{}, reply *ContextErrReply) error { + err := c.ctx.Err() + *reply = ContextErrReply{ + Err: err, + } + return nil +} + +func (c *ContextServer) Value(key interface{}, reply *ContextValueReply) error { + v := c.ctx.Value(key) + *reply = ContextValueReply{ + Value: v, + } + return nil +} + +type ContextErrReply struct { + Err error +} + +type ContextDeadlineReply struct { + Deadline time.Time + Ok bool +} + +type ContextValueReply struct { + Value interface{} +} diff --git a/logical/request.go b/logical/request.go index edde0417fd6b..1808840a4664 100644 --- a/logical/request.go +++ b/logical/request.go @@ -1,6 +1,7 @@ package logical import ( + "context" "errors" "fmt" "strings" @@ -55,6 +56,10 @@ type Request struct { // Id is the uuid associated with each request ID string `json:"id" structs:"id" mapstructure:"id" sentinel:""` + // Context provides the context interface for this request. It can be used + // to cancel a request early. + Context context.Context + // If set, the name given to the replication secondary where this request // originated ReplicationCluster string `json:"replication_cluster" structs:"replication_cluster" mapstructure:"replication_cluster" sentinel:""` diff --git a/vault/request_handling.go b/vault/request_handling.go index 7fb7ea1d3241..67ffa500ca7e 100644 --- a/vault/request_handling.go +++ b/vault/request_handling.go @@ -1,6 +1,7 @@ package vault import ( + "context" "fmt" "strings" "time" @@ -43,6 +44,10 @@ func (c *Core) HandleRequest(req *logical.Request) (resp *logical.Response, err return logical.ErrorResponse("cannot write to a path ending in '/'"), nil } + var cancel context.CancelFunc + req.Context, cancel = context.WithTimeout(c.requestContext, 30*time.Second) + defer cancel() + var auth *logical.Auth if c.router.LoginPath(req.Path) { resp, auth, err = c.handleLoginRequest(req) From ee85dd1427b25caee0b11cad10a1a26078f79375 Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Wed, 29 Nov 2017 01:37:51 -0800 Subject: [PATCH 2/9] Start work on moving the database plugins to gRPC in order to pass context --- Makefile | 1 + builtin/logical/database/dbplugin/client.go | 104 ++++ .../database/dbplugin/pb/database.pb.go | 557 ++++++++++++++++++ .../database/dbplugin/pb/database.proto | 58 ++ builtin/logical/database/dbplugin/server.go | 92 +++ 5 files changed, 812 insertions(+) create mode 100644 builtin/logical/database/dbplugin/pb/database.pb.go create mode 100644 builtin/logical/database/dbplugin/pb/database.proto diff --git a/Makefile b/Makefile index ccb556ec2e99..61179b96896b 100644 --- a/Makefile +++ b/Makefile @@ -83,6 +83,7 @@ proto: protoc -I helper/storagepacker helper/storagepacker/types.proto --go_out=plugins=grpc:helper/storagepacker protoc -I helper/forwarding -I vault -I ../../.. helper/forwarding/types.proto --go_out=plugins=grpc:helper/forwarding protoc -I helper/identity -I ../../.. helper/identity/types.proto --go_out=plugins=grpc:helper/identity + protoc builtin/logical/database/dbplugin/pb/*.proto --go_out=plugins=grpc:. sed -i -e 's/Idp/IDP/' -e 's/Url/URL/' -e 's/Id/ID/' -e 's/EntityId/EntityID/' -e 's/Api/API/' -e 's/Qr/QR/' -e 's/protobuf:"/sentinel:"" protobuf:"/' helper/identity/types.pb.go helper/storagepacker/types.pb.go fmtcheck: diff --git a/builtin/logical/database/dbplugin/client.go b/builtin/logical/database/dbplugin/client.go index 6df39489fea0..3104156d6408 100644 --- a/builtin/logical/database/dbplugin/client.go +++ b/builtin/logical/database/dbplugin/client.go @@ -1,12 +1,16 @@ package dbplugin import ( + "context" + "encoding/json" "fmt" "net/rpc" "sync" "time" + "github.com/golang/protobuf/ptypes" "github.com/hashicorp/go-plugin" + "github.com/hashicorp/vault/builtin/logical/database/dbplugin/pb" "github.com/hashicorp/vault/helper/pluginutil" log "github.com/mgutz/logxi/v1" ) @@ -64,6 +68,106 @@ func newPluginClient(sys pluginutil.RunnerUtil, pluginRunner *pluginutil.PluginR }, nil } +// ---- gRPC client domain ---- + +type gRPCClient struct { + client pb.DatabaseClient +} + +func (c gRPCClient) Type() (string, error) { + resp, err := c.client.Type(context.Background(), &pb.Empty{}) + if err != nil { + return "", err + } + + return resp.Type, err +} + +func (c gRPCClient) CreateUser(statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error) { + s := &pb.Statements{ + CreationStatements: statements.CreationStatements, + RevocationStatements: statements.RevocationStatements, + RollbackStatements: statements.RollbackStatements, + RenewStatements: statements.RenewStatements, + } + + u := &pb.UsernameConfig{ + DisplayName: usernameConfig.DisplayName, + RoleName: usernameConfig.RoleName, + } + + t, err := ptypes.TimestampProto(expiration) + if err != nil { + return "", "", err + } + + resp, err := c.client.CreateUser(context.Background(), &pb.CreateUserRequest{ + Statements: s, + UsernameConfig: u, + Expiration: t, + }) + if err != nil { + return "", "", err + } + + return resp.Username, resp.Password, err +} + +func (c *gRPCClient) RenewUser(statements Statements, username string, expiration time.Time) error { + s := &pb.Statements{ + CreationStatements: statements.CreationStatements, + RevocationStatements: statements.RevocationStatements, + RollbackStatements: statements.RollbackStatements, + RenewStatements: statements.RenewStatements, + } + + t, err := ptypes.TimestampProto(expiration) + if err != nil { + return err + } + + _, err = c.client.RenewUser(context.Background(), &pb.RenewUserRequest{ + Statements: s, + Expiration: t, + }) + + return err +} + +func (c *gRPCClient) RevokeUser(statements Statements, username string) error { + s := &pb.Statements{ + CreationStatements: statements.CreationStatements, + RevocationStatements: statements.RevocationStatements, + RollbackStatements: statements.RollbackStatements, + RenewStatements: statements.RenewStatements, + } + + _, err := c.client.RevokeUser(context.Background(), &pb.RevokeUserRequest{ + Statements: s, + }) + + return err +} + +func (c *gRPCClient) Initialize(config map[string]interface{}, verifyConnection bool) error { + configRaw, err := json.Marshal(config) + if err != nil { + return err + } + + _, err = c.client.Initialize(context.Background(), &pb.InitializeRequest{ + Config: string(configRaw[:]), + VerifyConnection: verifyConnection, + }) + + return err +} + +func (c *gRPCClient) Close() error { + _, err := c.client.Close(context.Background(), &pb.Empty{}) + return err +} + // ---- RPC client domain ---- // databasePluginRPCClient implements Database and is used on the client to diff --git a/builtin/logical/database/dbplugin/pb/database.pb.go b/builtin/logical/database/dbplugin/pb/database.pb.go new file mode 100644 index 000000000000..0408dab0edec --- /dev/null +++ b/builtin/logical/database/dbplugin/pb/database.pb.go @@ -0,0 +1,557 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: builtin/logical/database/dbplugin/pb/database.proto + +/* +Package pb is a generated protocol buffer package. + +It is generated from these files: + builtin/logical/database/dbplugin/pb/database.proto + +It has these top-level messages: + InitializeRequest + CreateUserRequest + RenewUserRequest + RevokeUserRequest + Statements + UsernameConfig + CreateUserResponse + TypeResponse + Empty +*/ +package pb + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import google_protobuf "github.com/golang/protobuf/ptypes/timestamp" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type InitializeRequest struct { + Config string `protobuf:"bytes,1,opt,name=config" json:"config,omitempty"` + VerifyConnection bool `protobuf:"varint,2,opt,name=verify_connection,json=verifyConnection" json:"verify_connection,omitempty"` +} + +func (m *InitializeRequest) Reset() { *m = InitializeRequest{} } +func (m *InitializeRequest) String() string { return proto.CompactTextString(m) } +func (*InitializeRequest) ProtoMessage() {} +func (*InitializeRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *InitializeRequest) GetConfig() string { + if m != nil { + return m.Config + } + return "" +} + +func (m *InitializeRequest) GetVerifyConnection() bool { + if m != nil { + return m.VerifyConnection + } + return false +} + +type CreateUserRequest struct { + Statements *Statements `protobuf:"bytes,1,opt,name=statements" json:"statements,omitempty"` + UsernameConfig *UsernameConfig `protobuf:"bytes,2,opt,name=username_config,json=usernameConfig" json:"username_config,omitempty"` + Expiration *google_protobuf.Timestamp `protobuf:"bytes,3,opt,name=expiration" json:"expiration,omitempty"` +} + +func (m *CreateUserRequest) Reset() { *m = CreateUserRequest{} } +func (m *CreateUserRequest) String() string { return proto.CompactTextString(m) } +func (*CreateUserRequest) ProtoMessage() {} +func (*CreateUserRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *CreateUserRequest) GetStatements() *Statements { + if m != nil { + return m.Statements + } + return nil +} + +func (m *CreateUserRequest) GetUsernameConfig() *UsernameConfig { + if m != nil { + return m.UsernameConfig + } + return nil +} + +func (m *CreateUserRequest) GetExpiration() *google_protobuf.Timestamp { + if m != nil { + return m.Expiration + } + return nil +} + +type RenewUserRequest struct { + Statements *Statements `protobuf:"bytes,1,opt,name=statements" json:"statements,omitempty"` + Username string `protobuf:"bytes,2,opt,name=username" json:"username,omitempty"` + Expiration *google_protobuf.Timestamp `protobuf:"bytes,3,opt,name=expiration" json:"expiration,omitempty"` +} + +func (m *RenewUserRequest) Reset() { *m = RenewUserRequest{} } +func (m *RenewUserRequest) String() string { return proto.CompactTextString(m) } +func (*RenewUserRequest) ProtoMessage() {} +func (*RenewUserRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *RenewUserRequest) GetStatements() *Statements { + if m != nil { + return m.Statements + } + return nil +} + +func (m *RenewUserRequest) GetUsername() string { + if m != nil { + return m.Username + } + return "" +} + +func (m *RenewUserRequest) GetExpiration() *google_protobuf.Timestamp { + if m != nil { + return m.Expiration + } + return nil +} + +type RevokeUserRequest struct { + Statements *Statements `protobuf:"bytes,1,opt,name=statements" json:"statements,omitempty"` + Username string `protobuf:"bytes,2,opt,name=username" json:"username,omitempty"` +} + +func (m *RevokeUserRequest) Reset() { *m = RevokeUserRequest{} } +func (m *RevokeUserRequest) String() string { return proto.CompactTextString(m) } +func (*RevokeUserRequest) ProtoMessage() {} +func (*RevokeUserRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + +func (m *RevokeUserRequest) GetStatements() *Statements { + if m != nil { + return m.Statements + } + return nil +} + +func (m *RevokeUserRequest) GetUsername() string { + if m != nil { + return m.Username + } + return "" +} + +type Statements struct { + CreationStatements string `protobuf:"bytes,1,opt,name=creation_statements,json=creationStatements" json:"creation_statements,omitempty"` + RevocationStatements string `protobuf:"bytes,2,opt,name=revocation_statements,json=revocationStatements" json:"revocation_statements,omitempty"` + RollbackStatements string `protobuf:"bytes,3,opt,name=rollback_statements,json=rollbackStatements" json:"rollback_statements,omitempty"` + RenewStatements string `protobuf:"bytes,4,opt,name=renew_statements,json=renewStatements" json:"renew_statements,omitempty"` +} + +func (m *Statements) Reset() { *m = Statements{} } +func (m *Statements) String() string { return proto.CompactTextString(m) } +func (*Statements) ProtoMessage() {} +func (*Statements) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } + +func (m *Statements) GetCreationStatements() string { + if m != nil { + return m.CreationStatements + } + return "" +} + +func (m *Statements) GetRevocationStatements() string { + if m != nil { + return m.RevocationStatements + } + return "" +} + +func (m *Statements) GetRollbackStatements() string { + if m != nil { + return m.RollbackStatements + } + return "" +} + +func (m *Statements) GetRenewStatements() string { + if m != nil { + return m.RenewStatements + } + return "" +} + +type UsernameConfig struct { + DisplayName string `protobuf:"bytes,1,opt,name=DisplayName" json:"DisplayName,omitempty"` + RoleName string `protobuf:"bytes,2,opt,name=RoleName" json:"RoleName,omitempty"` +} + +func (m *UsernameConfig) Reset() { *m = UsernameConfig{} } +func (m *UsernameConfig) String() string { return proto.CompactTextString(m) } +func (*UsernameConfig) ProtoMessage() {} +func (*UsernameConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } + +func (m *UsernameConfig) GetDisplayName() string { + if m != nil { + return m.DisplayName + } + return "" +} + +func (m *UsernameConfig) GetRoleName() string { + if m != nil { + return m.RoleName + } + return "" +} + +type CreateUserResponse struct { + Username string `protobuf:"bytes,1,opt,name=username" json:"username,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password" json:"password,omitempty"` +} + +func (m *CreateUserResponse) Reset() { *m = CreateUserResponse{} } +func (m *CreateUserResponse) String() string { return proto.CompactTextString(m) } +func (*CreateUserResponse) ProtoMessage() {} +func (*CreateUserResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } + +func (m *CreateUserResponse) GetUsername() string { + if m != nil { + return m.Username + } + return "" +} + +func (m *CreateUserResponse) GetPassword() string { + if m != nil { + return m.Password + } + return "" +} + +type TypeResponse struct { + Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` +} + +func (m *TypeResponse) Reset() { *m = TypeResponse{} } +func (m *TypeResponse) String() string { return proto.CompactTextString(m) } +func (*TypeResponse) ProtoMessage() {} +func (*TypeResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } + +func (m *TypeResponse) GetType() string { + if m != nil { + return m.Type + } + return "" +} + +type Empty struct { +} + +func (m *Empty) Reset() { *m = Empty{} } +func (m *Empty) String() string { return proto.CompactTextString(m) } +func (*Empty) ProtoMessage() {} +func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } + +func init() { + proto.RegisterType((*InitializeRequest)(nil), "pb.InitializeRequest") + proto.RegisterType((*CreateUserRequest)(nil), "pb.CreateUserRequest") + proto.RegisterType((*RenewUserRequest)(nil), "pb.RenewUserRequest") + proto.RegisterType((*RevokeUserRequest)(nil), "pb.RevokeUserRequest") + proto.RegisterType((*Statements)(nil), "pb.Statements") + proto.RegisterType((*UsernameConfig)(nil), "pb.UsernameConfig") + proto.RegisterType((*CreateUserResponse)(nil), "pb.CreateUserResponse") + proto.RegisterType((*TypeResponse)(nil), "pb.TypeResponse") + proto.RegisterType((*Empty)(nil), "pb.Empty") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// Client API for Database service + +type DatabaseClient interface { + Type(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TypeResponse, error) + CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error) + RenewUser(ctx context.Context, in *RenewUserRequest, opts ...grpc.CallOption) (*Empty, error) + RevokeUser(ctx context.Context, in *RevokeUserRequest, opts ...grpc.CallOption) (*Empty, error) + Initialize(ctx context.Context, in *InitializeRequest, opts ...grpc.CallOption) (*Empty, error) + Close(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) +} + +type databaseClient struct { + cc *grpc.ClientConn +} + +func NewDatabaseClient(cc *grpc.ClientConn) DatabaseClient { + return &databaseClient{cc} +} + +func (c *databaseClient) Type(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TypeResponse, error) { + out := new(TypeResponse) + err := grpc.Invoke(ctx, "/pb.Database/Type", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error) { + out := new(CreateUserResponse) + err := grpc.Invoke(ctx, "/pb.Database/CreateUser", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) RenewUser(ctx context.Context, in *RenewUserRequest, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := grpc.Invoke(ctx, "/pb.Database/RenewUser", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) RevokeUser(ctx context.Context, in *RevokeUserRequest, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := grpc.Invoke(ctx, "/pb.Database/RevokeUser", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) Initialize(ctx context.Context, in *InitializeRequest, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := grpc.Invoke(ctx, "/pb.Database/Initialize", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) Close(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := grpc.Invoke(ctx, "/pb.Database/Close", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for Database service + +type DatabaseServer interface { + Type(context.Context, *Empty) (*TypeResponse, error) + CreateUser(context.Context, *CreateUserRequest) (*CreateUserResponse, error) + RenewUser(context.Context, *RenewUserRequest) (*Empty, error) + RevokeUser(context.Context, *RevokeUserRequest) (*Empty, error) + Initialize(context.Context, *InitializeRequest) (*Empty, error) + Close(context.Context, *Empty) (*Empty, error) +} + +func RegisterDatabaseServer(s *grpc.Server, srv DatabaseServer) { + s.RegisterService(&_Database_serviceDesc, srv) +} + +func _Database_Type_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).Type(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Database/Type", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).Type(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_CreateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).CreateUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Database/CreateUser", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).CreateUser(ctx, req.(*CreateUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_RenewUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RenewUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).RenewUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Database/RenewUser", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).RenewUser(ctx, req.(*RenewUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_RevokeUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RevokeUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).RevokeUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Database/RevokeUser", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).RevokeUser(ctx, req.(*RevokeUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_Initialize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InitializeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).Initialize(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Database/Initialize", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).Initialize(ctx, req.(*InitializeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_Close_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).Close(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Database/Close", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).Close(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +var _Database_serviceDesc = grpc.ServiceDesc{ + ServiceName: "pb.Database", + HandlerType: (*DatabaseServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Type", + Handler: _Database_Type_Handler, + }, + { + MethodName: "CreateUser", + Handler: _Database_CreateUser_Handler, + }, + { + MethodName: "RenewUser", + Handler: _Database_RenewUser_Handler, + }, + { + MethodName: "RevokeUser", + Handler: _Database_RevokeUser_Handler, + }, + { + MethodName: "Initialize", + Handler: _Database_Initialize_Handler, + }, + { + MethodName: "Close", + Handler: _Database_Close_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "builtin/logical/database/dbplugin/pb/database.proto", +} + +func init() { + proto.RegisterFile("builtin/logical/database/dbplugin/pb/database.proto", fileDescriptor0) +} + +var fileDescriptor0 = []byte{ + // 541 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xcd, 0x6e, 0xd3, 0x40, + 0x10, 0x96, 0xd3, 0xb4, 0x24, 0x53, 0x94, 0x26, 0x4b, 0x5b, 0x55, 0x96, 0x10, 0x91, 0xb9, 0x14, + 0x81, 0x6c, 0xa9, 0xb9, 0xd1, 0x63, 0xca, 0x01, 0x09, 0xe5, 0x60, 0x5a, 0x89, 0x5b, 0xb4, 0x76, + 0x26, 0xd1, 0xaa, 0x9b, 0xdd, 0xc5, 0xbb, 0x4e, 0x09, 0x6f, 0x02, 0xcf, 0xc2, 0x33, 0xf0, 0x4c, + 0x68, 0xd7, 0xf1, 0x5f, 0x72, 0xac, 0xb8, 0xed, 0xcc, 0x7c, 0xdf, 0xcc, 0xe7, 0xf9, 0x31, 0x4c, + 0x92, 0x9c, 0x71, 0xc3, 0x44, 0xc4, 0xe5, 0x8a, 0xa5, 0x94, 0x47, 0x0b, 0x6a, 0x68, 0x42, 0x35, + 0x46, 0x8b, 0x44, 0xf1, 0x7c, 0xc5, 0x44, 0xa4, 0x92, 0xca, 0x19, 0xaa, 0x4c, 0x1a, 0x49, 0x3a, + 0x2a, 0xf1, 0xdf, 0xac, 0xa4, 0x5c, 0x71, 0x8c, 0x9c, 0x27, 0xc9, 0x97, 0x91, 0x61, 0x6b, 0xd4, + 0x86, 0xae, 0x55, 0x01, 0x0a, 0xbe, 0xc1, 0xe8, 0xb3, 0x60, 0x86, 0x51, 0xce, 0x7e, 0x62, 0x8c, + 0xdf, 0x73, 0xd4, 0x86, 0x5c, 0xc2, 0x49, 0x2a, 0xc5, 0x92, 0xad, 0xae, 0xbc, 0xb1, 0x77, 0xdd, + 0x8f, 0x77, 0x16, 0x79, 0x0f, 0xa3, 0x0d, 0x66, 0x6c, 0xb9, 0x9d, 0xa7, 0x52, 0x08, 0x4c, 0x0d, + 0x93, 0xe2, 0xaa, 0x33, 0xf6, 0xae, 0x7b, 0xf1, 0xb0, 0x08, 0x4c, 0x2b, 0x7f, 0xf0, 0xc7, 0x83, + 0xd1, 0x34, 0x43, 0x6a, 0xf0, 0x41, 0x63, 0x56, 0xa6, 0x0e, 0x01, 0xb4, 0xa1, 0x06, 0xd7, 0x28, + 0x8c, 0x76, 0xe9, 0x4f, 0x6f, 0x06, 0xa1, 0x4a, 0xc2, 0xaf, 0x95, 0x37, 0x6e, 0x20, 0xc8, 0x2d, + 0x9c, 0xe5, 0x1a, 0x33, 0x41, 0xd7, 0x38, 0xdf, 0x69, 0xea, 0x38, 0x12, 0xb1, 0xa4, 0x87, 0x5d, + 0x68, 0xea, 0x22, 0xf1, 0x20, 0x6f, 0xd9, 0xe4, 0x23, 0x00, 0xfe, 0x50, 0x2c, 0xa3, 0x4e, 0xe8, + 0x91, 0xe3, 0xf9, 0x61, 0xd1, 0x92, 0xb0, 0x6c, 0x49, 0x78, 0x5f, 0xb6, 0x24, 0x6e, 0xa0, 0x83, + 0xdf, 0x1e, 0x0c, 0x63, 0x14, 0xf8, 0xf4, 0x1c, 0xf5, 0x3e, 0xf4, 0x4a, 0x49, 0x4e, 0x76, 0x3f, + 0xae, 0xec, 0x67, 0x89, 0x9b, 0xc3, 0x28, 0xc6, 0x8d, 0x7c, 0xc4, 0xff, 0x24, 0x2e, 0xf8, 0xeb, + 0x01, 0xd4, 0x34, 0x12, 0xc1, 0xab, 0xd4, 0x8e, 0x92, 0x49, 0x31, 0xdf, 0xab, 0xd1, 0x8f, 0x49, + 0x19, 0x6a, 0x10, 0x26, 0x70, 0x91, 0xe1, 0x46, 0xa6, 0x07, 0x94, 0xa2, 0xd0, 0x79, 0x1d, 0x6c, + 0x57, 0xc9, 0x24, 0xe7, 0x09, 0x4d, 0x1f, 0x9b, 0x94, 0xa3, 0xa2, 0x4a, 0x19, 0x6a, 0x10, 0xde, + 0xc1, 0x30, 0xb3, 0x23, 0x6a, 0xa2, 0xbb, 0x0e, 0x7d, 0xe6, 0xfc, 0x35, 0x34, 0x98, 0xc1, 0xa0, + 0xbd, 0x2c, 0x64, 0x0c, 0xa7, 0x77, 0x4c, 0x2b, 0x4e, 0xb7, 0x33, 0xdb, 0x81, 0xe2, 0x5b, 0x9a, + 0x2e, 0xdb, 0xa0, 0x58, 0x72, 0x9c, 0x35, 0x1a, 0x54, 0xda, 0xc1, 0x17, 0x20, 0xcd, 0xe5, 0xd6, + 0x4a, 0x0a, 0x8d, 0xad, 0x96, 0x7a, 0x7b, 0xf3, 0xf6, 0xa1, 0xa7, 0xa8, 0xd6, 0x4f, 0x32, 0x5b, + 0x94, 0xd9, 0x4a, 0x3b, 0x08, 0xe0, 0xe5, 0xfd, 0x56, 0x61, 0x95, 0x87, 0x40, 0xd7, 0x6c, 0x55, + 0x99, 0xc3, 0xbd, 0x83, 0x17, 0x70, 0xfc, 0x69, 0xad, 0xcc, 0xf6, 0xe6, 0x57, 0x07, 0x7a, 0x77, + 0xbb, 0x53, 0x27, 0x6f, 0xa1, 0x6b, 0x99, 0xa4, 0x6f, 0x07, 0xed, 0xe2, 0xfe, 0xd0, 0x3e, 0x5b, + 0xe9, 0x6e, 0x01, 0x6a, 0xb1, 0xe4, 0xc2, 0xc6, 0x0f, 0x2e, 0xd3, 0xbf, 0xdc, 0x77, 0xef, 0xc8, + 0x1f, 0xa0, 0x5f, 0xdd, 0x01, 0x39, 0xb7, 0xa0, 0xfd, 0xb3, 0xf0, 0xeb, 0xe2, 0x76, 0x09, 0xeb, + 0xcd, 0x2c, 0x4a, 0x1d, 0x6c, 0xea, 0x1e, 0xbe, 0xfe, 0xff, 0x14, 0xf8, 0x83, 0xff, 0x51, 0x13, + 0xff, 0x1a, 0x8e, 0xa7, 0x5c, 0xea, 0xd6, 0x07, 0xd7, 0xcf, 0xe4, 0xc4, 0x1d, 0xce, 0xe4, 0x5f, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x89, 0x25, 0x43, 0x3e, 0x31, 0x05, 0x00, 0x00, +} diff --git a/builtin/logical/database/dbplugin/pb/database.proto b/builtin/logical/database/dbplugin/pb/database.proto new file mode 100644 index 000000000000..185128f8cee2 --- /dev/null +++ b/builtin/logical/database/dbplugin/pb/database.proto @@ -0,0 +1,58 @@ +syntax = "proto3"; +package pb; + +import "google/protobuf/timestamp.proto"; + +message InitializeRequest { + string config = 1; + bool verify_connection = 2; +} + +message CreateUserRequest { + Statements statements = 1; + UsernameConfig username_config = 2; + google.protobuf.Timestamp expiration = 3; +} + +message RenewUserRequest { + Statements statements = 1; + string username = 2; + google.protobuf.Timestamp expiration = 3; +} + +message RevokeUserRequest { + Statements statements = 1; + string username = 2; +} + +message Statements { + string creation_statements = 1; + string revocation_statements = 2; + string rollback_statements = 3; + string renew_statements = 4; +} + +message UsernameConfig { + string DisplayName = 1; + string RoleName = 2; +} + +message CreateUserResponse { + string username = 1; + string password = 2; +} + +message TypeResponse { + string type = 1; +} + +message Empty {} + +service Database { + rpc Type(Empty) returns (TypeResponse); + rpc CreateUser(CreateUserRequest) returns (CreateUserResponse); + rpc RenewUser(RenewUserRequest) returns (Empty); + rpc RevokeUser(RevokeUserRequest) returns (Empty); + rpc Initialize(InitializeRequest) returns (Empty); + rpc Close(Empty) returns (Empty); +} diff --git a/builtin/logical/database/dbplugin/server.go b/builtin/logical/database/dbplugin/server.go index 381f0ae2a1f4..a675b943bdf3 100644 --- a/builtin/logical/database/dbplugin/server.go +++ b/builtin/logical/database/dbplugin/server.go @@ -1,9 +1,13 @@ package dbplugin import ( + "context" "crypto/tls" + "encoding/json" + "github.com/golang/protobuf/ptypes" "github.com/hashicorp/go-plugin" + "github.com/hashicorp/vault/builtin/logical/database/dbplugin/pb" ) // Serve is called from within a plugin and wraps the provided @@ -26,6 +30,94 @@ func Serve(db Database, tlsProvider func() (*tls.Config, error)) { }) } +// ---- gRPC Server domain ---- + +type gRPCServer struct { + impl Database +} + +func (s *gRPCServer) Type(context.Context, *pb.Empty) (*pb.TypeResponse, error) { + t, err := s.impl.Type() + if err != nil { + return nil, err + } + + return &pb.TypeResponse{ + Type: t, + }, nil +} + +func (s *gRPCServer) CreateUser(_ context.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) { + statements := Statements{ + CreationStatements: req.Statements.CreationStatements, + RevocationStatements: req.Statements.RevocationStatements, + RollbackStatements: req.Statements.RollbackStatements, + RenewStatements: req.Statements.RenewStatements, + } + + usernameConfig := UsernameConfig{ + DisplayName: req.UsernameConfig.DisplayName, + RoleName: req.UsernameConfig.RoleName, + } + + e, err := ptypes.Timestamp(req.Expiration) + if err != nil { + return nil, err + } + + u, p, err := s.impl.CreateUser(statements, usernameConfig, e) + + return &pb.CreateUserResponse{ + Username: u, + Password: p, + }, err +} + +func (s *gRPCServer) RenewUser(_ context.Context, req *pb.RenewUserRequest) (*pb.Empty, error) { + statements := Statements{ + CreationStatements: req.Statements.CreationStatements, + RevocationStatements: req.Statements.RevocationStatements, + RollbackStatements: req.Statements.RollbackStatements, + RenewStatements: req.Statements.RenewStatements, + } + + e, err := ptypes.Timestamp(req.Expiration) + if err != nil { + return nil, err + } + err = s.impl.RenewUser(statements, req.Username, e) + return &pb.Empty{}, err +} + +func (s *gRPCServer) RevokeUser(_ context.Context, req *pb.RevokeUserRequest) (*pb.Empty, error) { + statements := Statements{ + CreationStatements: req.Statements.CreationStatements, + RevocationStatements: req.Statements.RevocationStatements, + RollbackStatements: req.Statements.RollbackStatements, + RenewStatements: req.Statements.RenewStatements, + } + + err := s.impl.RevokeUser(statements, req.Username) + return &pb.Empty{}, err +} + +func (s *gRPCServer) Initialize(ctx context.Context, req *pb.InitializeRequest) (*pb.Empty, error) { + config := map[string]interface{}{} + + err := json.Unmarshal([]byte(req.Config), config) + if err != nil { + return nil, err + } + + err = s.impl.Initialize(config, req.VerifyConnection) + return &pb.Empty{}, err +} + +func (s *gRPCServer) Close(_ context.Context, _ *pb.Empty) (*pb.Empty, error) { + s.impl.Close() + return &pb.Empty{}, nil +} + // ---- RPC server domain ---- // databasePluginRPCServer implements an RPC version of Database and is run From d90f8d860b1a7d4c1d32c4fc3c3d0c6b7b4dbd25 Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Wed, 29 Nov 2017 02:17:46 -0800 Subject: [PATCH 3/9] Add context to builtin database plugins --- builtin/logical/database/backend.go | 5 +- builtin/logical/database/dbplugin/client.go | 96 +++---------------- .../database/dbplugin/databasemiddleware.go | 33 +++---- builtin/logical/database/dbplugin/plugin.go | 56 +++-------- builtin/logical/database/dbplugin/server.go | 59 ++---------- .../database/path_config_connection.go | 4 +- builtin/logical/database/path_creds_create.go | 4 +- builtin/logical/database/secret_creds.go | 8 +- plugins/database/cassandra/cassandra.go | 9 +- .../database/cassandra/connection_producer.go | 3 +- plugins/database/hana/hana.go | 9 +- .../database/mongodb/connection_producer.go | 3 +- plugins/database/mongodb/mongodb.go | 9 +- plugins/database/mssql/mssql.go | 9 +- plugins/database/mysql/mysql.go | 9 +- plugins/database/postgresql/postgresql.go | 9 +- plugins/helper/database/connutil/connutil.go | 3 +- plugins/helper/database/connutil/sql.go | 3 +- 18 files changed, 108 insertions(+), 223 deletions(-) diff --git a/builtin/logical/database/backend.go b/builtin/logical/database/backend.go index a8a54a7cde01..8288481c437c 100644 --- a/builtin/logical/database/backend.go +++ b/builtin/logical/database/backend.go @@ -1,6 +1,7 @@ package database import ( + "context" "fmt" "net/rpc" "strings" @@ -87,7 +88,7 @@ func (b *databaseBackend) getDBObj(name string) (dbplugin.Database, bool) { // This function creates a new db object from the stored configuration and // caches it in the connections map. The caller of this function needs to hold // the backend's write lock -func (b *databaseBackend) createDBObj(s logical.Storage, name string) (dbplugin.Database, error) { +func (b *databaseBackend) createDBObj(ctx context.Context, s logical.Storage, name string) (dbplugin.Database, error) { db, ok := b.connections[name] if ok { return db, nil @@ -103,7 +104,7 @@ func (b *databaseBackend) createDBObj(s logical.Storage, name string) (dbplugin. return nil, err } - err = db.Initialize(config.ConnectionDetails, true) + err = db.Initialize(ctx, config.ConnectionDetails, true) if err != nil { return nil, err } diff --git a/builtin/logical/database/dbplugin/client.go b/builtin/logical/database/dbplugin/client.go index 3104156d6408..217f885d6669 100644 --- a/builtin/logical/database/dbplugin/client.go +++ b/builtin/logical/database/dbplugin/client.go @@ -3,8 +3,6 @@ package dbplugin import ( "context" "encoding/json" - "fmt" - "net/rpc" "sync" "time" @@ -21,11 +19,11 @@ type DatabasePluginClient struct { client *plugin.Client sync.Mutex - *databasePluginRPCClient + *gRPCClient } func (dc *DatabasePluginClient) Close() error { - err := dc.databasePluginRPCClient.Close() + err := dc.gRPCClient.Close() dc.client.Kill() return err @@ -59,12 +57,12 @@ func newPluginClient(sys pluginutil.RunnerUtil, pluginRunner *pluginutil.PluginR // We should have a database type now. This feels like a normal interface // implementation but is in fact over an RPC connection. - databaseRPC := raw.(*databasePluginRPCClient) + databaseRPC := raw.(*gRPCClient) // Wrap RPC implimentation in DatabasePluginClient return &DatabasePluginClient{ - client: client, - databasePluginRPCClient: databaseRPC, + client: client, + gRPCClient: databaseRPC, }, nil } @@ -83,7 +81,7 @@ func (c gRPCClient) Type() (string, error) { return resp.Type, err } -func (c gRPCClient) CreateUser(statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error) { +func (c gRPCClient) CreateUser(ctx context.Context, statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error) { s := &pb.Statements{ CreationStatements: statements.CreationStatements, RevocationStatements: statements.RevocationStatements, @@ -101,7 +99,7 @@ func (c gRPCClient) CreateUser(statements Statements, usernameConfig UsernameCon return "", "", err } - resp, err := c.client.CreateUser(context.Background(), &pb.CreateUserRequest{ + resp, err := c.client.CreateUser(ctx, &pb.CreateUserRequest{ Statements: s, UsernameConfig: u, Expiration: t, @@ -113,7 +111,7 @@ func (c gRPCClient) CreateUser(statements Statements, usernameConfig UsernameCon return resp.Username, resp.Password, err } -func (c *gRPCClient) RenewUser(statements Statements, username string, expiration time.Time) error { +func (c *gRPCClient) RenewUser(ctx context.Context, statements Statements, username string, expiration time.Time) error { s := &pb.Statements{ CreationStatements: statements.CreationStatements, RevocationStatements: statements.RevocationStatements, @@ -126,7 +124,7 @@ func (c *gRPCClient) RenewUser(statements Statements, username string, expiratio return err } - _, err = c.client.RenewUser(context.Background(), &pb.RenewUserRequest{ + _, err = c.client.RenewUser(ctx, &pb.RenewUserRequest{ Statements: s, Expiration: t, }) @@ -134,7 +132,7 @@ func (c *gRPCClient) RenewUser(statements Statements, username string, expiratio return err } -func (c *gRPCClient) RevokeUser(statements Statements, username string) error { +func (c *gRPCClient) RevokeUser(ctx context.Context, statements Statements, username string) error { s := &pb.Statements{ CreationStatements: statements.CreationStatements, RevocationStatements: statements.RevocationStatements, @@ -142,20 +140,20 @@ func (c *gRPCClient) RevokeUser(statements Statements, username string) error { RenewStatements: statements.RenewStatements, } - _, err := c.client.RevokeUser(context.Background(), &pb.RevokeUserRequest{ + _, err := c.client.RevokeUser(ctx, &pb.RevokeUserRequest{ Statements: s, }) return err } -func (c *gRPCClient) Initialize(config map[string]interface{}, verifyConnection bool) error { +func (c *gRPCClient) Initialize(ctx context.Context, config map[string]interface{}, verifyConnection bool) error { configRaw, err := json.Marshal(config) if err != nil { return err } - _, err = c.client.Initialize(context.Background(), &pb.InitializeRequest{ + _, err = c.client.Initialize(ctx, &pb.InitializeRequest{ Config: string(configRaw[:]), VerifyConnection: verifyConnection, }) @@ -167,71 +165,3 @@ func (c *gRPCClient) Close() error { _, err := c.client.Close(context.Background(), &pb.Empty{}) return err } - -// ---- RPC client domain ---- - -// databasePluginRPCClient implements Database and is used on the client to -// make RPC calls to a plugin. -type databasePluginRPCClient struct { - client *rpc.Client -} - -func (dr *databasePluginRPCClient) Type() (string, error) { - var dbType string - err := dr.client.Call("Plugin.Type", struct{}{}, &dbType) - - return fmt.Sprintf("plugin-%s", dbType), err -} - -func (dr *databasePluginRPCClient) CreateUser(statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error) { - req := CreateUserRequest{ - Statements: statements, - UsernameConfig: usernameConfig, - Expiration: expiration, - } - - var resp CreateUserResponse - err = dr.client.Call("Plugin.CreateUser", req, &resp) - - return resp.Username, resp.Password, err -} - -func (dr *databasePluginRPCClient) RenewUser(statements Statements, username string, expiration time.Time) error { - req := RenewUserRequest{ - Statements: statements, - Username: username, - Expiration: expiration, - } - - err := dr.client.Call("Plugin.RenewUser", req, &struct{}{}) - - return err -} - -func (dr *databasePluginRPCClient) RevokeUser(statements Statements, username string) error { - req := RevokeUserRequest{ - Statements: statements, - Username: username, - } - - err := dr.client.Call("Plugin.RevokeUser", req, &struct{}{}) - - return err -} - -func (dr *databasePluginRPCClient) Initialize(conf map[string]interface{}, verifyConnection bool) error { - req := InitializeRequest{ - Config: conf, - VerifyConnection: verifyConnection, - } - - err := dr.client.Call("Plugin.Initialize", req, &struct{}{}) - - return err -} - -func (dr *databasePluginRPCClient) Close() error { - err := dr.client.Call("Plugin.Close", struct{}{}, &struct{}{}) - - return err -} diff --git a/builtin/logical/database/dbplugin/databasemiddleware.go b/builtin/logical/database/dbplugin/databasemiddleware.go index 87dfa6c3143d..b8eec1305828 100644 --- a/builtin/logical/database/dbplugin/databasemiddleware.go +++ b/builtin/logical/database/dbplugin/databasemiddleware.go @@ -1,6 +1,7 @@ package dbplugin import ( + "context" "time" metrics "github.com/armon/go-metrics" @@ -22,40 +23,40 @@ func (mw *databaseTracingMiddleware) Type() (string, error) { return mw.next.Type() } -func (mw *databaseTracingMiddleware) CreateUser(statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error) { +func (mw *databaseTracingMiddleware) CreateUser(ctx context.Context, statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error) { defer func(then time.Time) { mw.logger.Trace("database", "operation", "CreateUser", "status", "finished", "type", mw.typeStr, "err", err, "took", time.Since(then)) }(time.Now()) mw.logger.Trace("database", "operation", "CreateUser", "status", "started", "type", mw.typeStr) - return mw.next.CreateUser(statements, usernameConfig, expiration) + return mw.next.CreateUser(ctx, statements, usernameConfig, expiration) } -func (mw *databaseTracingMiddleware) RenewUser(statements Statements, username string, expiration time.Time) (err error) { +func (mw *databaseTracingMiddleware) RenewUser(ctx context.Context, statements Statements, username string, expiration time.Time) (err error) { defer func(then time.Time) { mw.logger.Trace("database", "operation", "RenewUser", "status", "finished", "type", mw.typeStr, "err", err, "took", time.Since(then)) }(time.Now()) mw.logger.Trace("database", "operation", "RenewUser", "status", "started", mw.typeStr) - return mw.next.RenewUser(statements, username, expiration) + return mw.next.RenewUser(ctx, statements, username, expiration) } -func (mw *databaseTracingMiddleware) RevokeUser(statements Statements, username string) (err error) { +func (mw *databaseTracingMiddleware) RevokeUser(ctx context.Context, statements Statements, username string) (err error) { defer func(then time.Time) { mw.logger.Trace("database", "operation", "RevokeUser", "status", "finished", "type", mw.typeStr, "err", err, "took", time.Since(then)) }(time.Now()) mw.logger.Trace("database", "operation", "RevokeUser", "status", "started", "type", mw.typeStr) - return mw.next.RevokeUser(statements, username) + return mw.next.RevokeUser(ctx, statements, username) } -func (mw *databaseTracingMiddleware) Initialize(conf map[string]interface{}, verifyConnection bool) (err error) { +func (mw *databaseTracingMiddleware) Initialize(ctx context.Context, conf map[string]interface{}, verifyConnection bool) (err error) { defer func(then time.Time) { mw.logger.Trace("database", "operation", "Initialize", "status", "finished", "type", mw.typeStr, "verify", verifyConnection, "err", err, "took", time.Since(then)) }(time.Now()) mw.logger.Trace("database", "operation", "Initialize", "status", "started", "type", mw.typeStr) - return mw.next.Initialize(conf, verifyConnection) + return mw.next.Initialize(ctx, conf, verifyConnection) } func (mw *databaseTracingMiddleware) Close() (err error) { @@ -81,7 +82,7 @@ func (mw *databaseMetricsMiddleware) Type() (string, error) { return mw.next.Type() } -func (mw *databaseMetricsMiddleware) CreateUser(statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error) { +func (mw *databaseMetricsMiddleware) CreateUser(ctx context.Context, statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error) { defer func(now time.Time) { metrics.MeasureSince([]string{"database", "CreateUser"}, now) metrics.MeasureSince([]string{"database", mw.typeStr, "CreateUser"}, now) @@ -94,10 +95,10 @@ func (mw *databaseMetricsMiddleware) CreateUser(statements Statements, usernameC metrics.IncrCounter([]string{"database", "CreateUser"}, 1) metrics.IncrCounter([]string{"database", mw.typeStr, "CreateUser"}, 1) - return mw.next.CreateUser(statements, usernameConfig, expiration) + return mw.next.CreateUser(ctx, statements, usernameConfig, expiration) } -func (mw *databaseMetricsMiddleware) RenewUser(statements Statements, username string, expiration time.Time) (err error) { +func (mw *databaseMetricsMiddleware) RenewUser(ctx context.Context, statements Statements, username string, expiration time.Time) (err error) { defer func(now time.Time) { metrics.MeasureSince([]string{"database", "RenewUser"}, now) metrics.MeasureSince([]string{"database", mw.typeStr, "RenewUser"}, now) @@ -110,10 +111,10 @@ func (mw *databaseMetricsMiddleware) RenewUser(statements Statements, username s metrics.IncrCounter([]string{"database", "RenewUser"}, 1) metrics.IncrCounter([]string{"database", mw.typeStr, "RenewUser"}, 1) - return mw.next.RenewUser(statements, username, expiration) + return mw.next.RenewUser(ctx, statements, username, expiration) } -func (mw *databaseMetricsMiddleware) RevokeUser(statements Statements, username string) (err error) { +func (mw *databaseMetricsMiddleware) RevokeUser(ctx context.Context, statements Statements, username string) (err error) { defer func(now time.Time) { metrics.MeasureSince([]string{"database", "RevokeUser"}, now) metrics.MeasureSince([]string{"database", mw.typeStr, "RevokeUser"}, now) @@ -126,10 +127,10 @@ func (mw *databaseMetricsMiddleware) RevokeUser(statements Statements, username metrics.IncrCounter([]string{"database", "RevokeUser"}, 1) metrics.IncrCounter([]string{"database", mw.typeStr, "RevokeUser"}, 1) - return mw.next.RevokeUser(statements, username) + return mw.next.RevokeUser(ctx, statements, username) } -func (mw *databaseMetricsMiddleware) Initialize(conf map[string]interface{}, verifyConnection bool) (err error) { +func (mw *databaseMetricsMiddleware) Initialize(ctx context.Context, conf map[string]interface{}, verifyConnection bool) (err error) { defer func(now time.Time) { metrics.MeasureSince([]string{"database", "Initialize"}, now) metrics.MeasureSince([]string{"database", mw.typeStr, "Initialize"}, now) @@ -142,7 +143,7 @@ func (mw *databaseMetricsMiddleware) Initialize(conf map[string]interface{}, ver metrics.IncrCounter([]string{"database", "Initialize"}, 1) metrics.IncrCounter([]string{"database", mw.typeStr, "Initialize"}, 1) - return mw.next.Initialize(conf, verifyConnection) + return mw.next.Initialize(ctx, conf, verifyConnection) } func (mw *databaseMetricsMiddleware) Close() (err error) { diff --git a/builtin/logical/database/dbplugin/plugin.go b/builtin/logical/database/dbplugin/plugin.go index 0becc9f4aa43..9c7f55e4e45f 100644 --- a/builtin/logical/database/dbplugin/plugin.go +++ b/builtin/logical/database/dbplugin/plugin.go @@ -1,11 +1,14 @@ package dbplugin import ( + "context" "fmt" - "net/rpc" "time" + "google.golang.org/grpc" + "github.com/hashicorp/go-plugin" + "github.com/hashicorp/vault/builtin/logical/database/dbplugin/pb" "github.com/hashicorp/vault/helper/pluginutil" log "github.com/mgutz/logxi/v1" ) @@ -13,11 +16,11 @@ import ( // Database is the interface that all database objects must implement. type Database interface { Type() (string, error) - CreateUser(statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error) - RenewUser(statements Statements, username string, expiration time.Time) error - RevokeUser(statements Statements, username string) error + CreateUser(ctx context.Context, statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error) + RenewUser(ctx context.Context, statements Statements, username string, expiration time.Time) error + RevokeUser(ctx context.Context, statements Statements, username string) error - Initialize(config map[string]interface{}, verifyConnection bool) error + Initialize(ctx context.Context, config map[string]interface{}, verifyConnection bool) error Close() error } @@ -96,7 +99,7 @@ func PluginFactory(pluginName string, sys pluginutil.LookRunnerUtil, logger log. // 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{ - ProtocolVersion: 3, + ProtocolVersion: 4, MagicCookieKey: "VAULT_DATABASE_PLUGIN", MagicCookieValue: "926a0820-aea2-be28-51d6-83cdf00e8edb", } @@ -104,44 +107,15 @@ var handshakeConfig = plugin.HandshakeConfig{ // DatabasePlugin implements go-plugin's Plugin interface. It has methods for // retrieving a server and a client instance of the plugin. type DatabasePlugin struct { + plugin.NetRPCUnsupportedPlugin impl Database } -func (d DatabasePlugin) Server(*plugin.MuxBroker) (interface{}, error) { - return &databasePluginRPCServer{impl: d.impl}, nil -} - -func (DatabasePlugin) Client(b *plugin.MuxBroker, c *rpc.Client) (interface{}, error) { - return &databasePluginRPCClient{client: c}, nil +func (d DatabasePlugin) GRPCServer(s *grpc.Server) error { + pb.RegisterDatabaseServer(s, &gRPCServer{impl: d.impl}) + return nil } -// ---- RPC Request Args Domain ---- - -type InitializeRequest struct { - Config map[string]interface{} - VerifyConnection bool -} - -type CreateUserRequest struct { - Statements Statements - UsernameConfig UsernameConfig - Expiration time.Time -} - -type RenewUserRequest struct { - Statements Statements - Username string - Expiration time.Time -} - -type RevokeUserRequest struct { - Statements Statements - Username string -} - -// ---- RPC Response Args Domain ---- - -type CreateUserResponse struct { - Username string - Password string +func (DatabasePlugin) GRPCClient(c *grpc.ClientConn) (interface{}, error) { + return &gRPCClient{client: pb.NewDatabaseClient(c)}, nil } diff --git a/builtin/logical/database/dbplugin/server.go b/builtin/logical/database/dbplugin/server.go index a675b943bdf3..a1286345496e 100644 --- a/builtin/logical/database/dbplugin/server.go +++ b/builtin/logical/database/dbplugin/server.go @@ -27,6 +27,7 @@ func Serve(db Database, tlsProvider func() (*tls.Config, error)) { HandshakeConfig: handshakeConfig, Plugins: pluginMap, TLSProvider: tlsProvider, + GRPCServer: plugin.DefaultGRPCServer, }) } @@ -47,7 +48,7 @@ func (s *gRPCServer) Type(context.Context, *pb.Empty) (*pb.TypeResponse, error) }, nil } -func (s *gRPCServer) CreateUser(_ context.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) { +func (s *gRPCServer) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) { statements := Statements{ CreationStatements: req.Statements.CreationStatements, RevocationStatements: req.Statements.RevocationStatements, @@ -65,7 +66,7 @@ func (s *gRPCServer) CreateUser(_ context.Context, req *pb.CreateUserRequest) (* return nil, err } - u, p, err := s.impl.CreateUser(statements, usernameConfig, e) + u, p, err := s.impl.CreateUser(ctx, statements, usernameConfig, e) return &pb.CreateUserResponse{ Username: u, @@ -73,7 +74,7 @@ func (s *gRPCServer) CreateUser(_ context.Context, req *pb.CreateUserRequest) (* }, err } -func (s *gRPCServer) RenewUser(_ context.Context, req *pb.RenewUserRequest) (*pb.Empty, error) { +func (s *gRPCServer) RenewUser(ctx context.Context, req *pb.RenewUserRequest) (*pb.Empty, error) { statements := Statements{ CreationStatements: req.Statements.CreationStatements, RevocationStatements: req.Statements.RevocationStatements, @@ -85,11 +86,11 @@ func (s *gRPCServer) RenewUser(_ context.Context, req *pb.RenewUserRequest) (*pb if err != nil { return nil, err } - err = s.impl.RenewUser(statements, req.Username, e) + err = s.impl.RenewUser(ctx, statements, req.Username, e) return &pb.Empty{}, err } -func (s *gRPCServer) RevokeUser(_ context.Context, req *pb.RevokeUserRequest) (*pb.Empty, error) { +func (s *gRPCServer) RevokeUser(ctx context.Context, req *pb.RevokeUserRequest) (*pb.Empty, error) { statements := Statements{ CreationStatements: req.Statements.CreationStatements, RevocationStatements: req.Statements.RevocationStatements, @@ -97,7 +98,7 @@ func (s *gRPCServer) RevokeUser(_ context.Context, req *pb.RevokeUserRequest) (* RenewStatements: req.Statements.RenewStatements, } - err := s.impl.RevokeUser(statements, req.Username) + err := s.impl.RevokeUser(ctx, statements, req.Username) return &pb.Empty{}, err } @@ -109,7 +110,7 @@ func (s *gRPCServer) Initialize(ctx context.Context, req *pb.InitializeRequest) return nil, err } - err = s.impl.Initialize(config, req.VerifyConnection) + err = s.impl.Initialize(ctx, config, req.VerifyConnection) return &pb.Empty{}, err } @@ -117,47 +118,3 @@ func (s *gRPCServer) Close(_ context.Context, _ *pb.Empty) (*pb.Empty, error) { s.impl.Close() return &pb.Empty{}, nil } - -// ---- RPC server domain ---- - -// databasePluginRPCServer implements an RPC version of Database and is run -// inside a plugin. It wraps an underlying implementation of Database. -type databasePluginRPCServer struct { - impl Database -} - -func (ds *databasePluginRPCServer) Type(_ struct{}, resp *string) error { - var err error - *resp, err = ds.impl.Type() - return err -} - -func (ds *databasePluginRPCServer) CreateUser(args *CreateUserRequest, resp *CreateUserResponse) error { - var err error - resp.Username, resp.Password, err = ds.impl.CreateUser(args.Statements, args.UsernameConfig, args.Expiration) - - return err -} - -func (ds *databasePluginRPCServer) RenewUser(args *RenewUserRequest, _ *struct{}) error { - err := ds.impl.RenewUser(args.Statements, args.Username, args.Expiration) - - return err -} - -func (ds *databasePluginRPCServer) RevokeUser(args *RevokeUserRequest, _ *struct{}) error { - err := ds.impl.RevokeUser(args.Statements, args.Username) - - return err -} - -func (ds *databasePluginRPCServer) Initialize(args *InitializeRequest, _ *struct{}) error { - err := ds.impl.Initialize(args.Config, args.VerifyConnection) - - return err -} - -func (ds *databasePluginRPCServer) Close(_ struct{}, _ *struct{}) error { - ds.impl.Close() - return nil -} diff --git a/builtin/logical/database/path_config_connection.go b/builtin/logical/database/path_config_connection.go index d1e6cb2923fc..8c280da928e3 100644 --- a/builtin/logical/database/path_config_connection.go +++ b/builtin/logical/database/path_config_connection.go @@ -62,7 +62,7 @@ func (b *databaseBackend) pathConnectionReset() framework.OperationFunc { b.clearConnection(name) // Execute plugin again, we don't need the object so throw away. - _, err := b.createDBObj(req.Storage, name) + _, err := b.createDBObj(req.Context, req.Storage, name) if err != nil { return nil, err } @@ -230,7 +230,7 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc { return logical.ErrorResponse(fmt.Sprintf("error creating database object: %s", err)), nil } - err = db.Initialize(config.ConnectionDetails, verifyConnection) + err = db.Initialize(req.Context, config.ConnectionDetails, verifyConnection) if err != nil { db.Close() return logical.ErrorResponse(fmt.Sprintf("error creating database object: %s", err)), nil diff --git a/builtin/logical/database/path_creds_create.go b/builtin/logical/database/path_creds_create.go index 610da726c606..111f63f5ac30 100644 --- a/builtin/logical/database/path_creds_create.go +++ b/builtin/logical/database/path_creds_create.go @@ -66,7 +66,7 @@ func (b *databaseBackend) pathCredsCreateRead() framework.OperationFunc { unlockFunc = b.Unlock // Create a new DB object - db, err = b.createDBObj(req.Storage, role.DBName) + db, err = b.createDBObj(req.Context, req.Storage, role.DBName) if err != nil { unlockFunc() return nil, fmt.Errorf("cound not retrieve db with name: %s, got error: %s", role.DBName, err) @@ -81,7 +81,7 @@ func (b *databaseBackend) pathCredsCreateRead() framework.OperationFunc { } // Create the user - username, password, err := db.CreateUser(role.Statements, usernameConfig, expiration) + username, password, err := db.CreateUser(req.Context, role.Statements, usernameConfig, expiration) // Unlock unlockFunc() if err != nil { diff --git a/builtin/logical/database/secret_creds.go b/builtin/logical/database/secret_creds.go index c3dfcb973368..2cf53125c450 100644 --- a/builtin/logical/database/secret_creds.go +++ b/builtin/logical/database/secret_creds.go @@ -60,7 +60,7 @@ func (b *databaseBackend) secretCredsRenew() framework.OperationFunc { unlockFunc = b.Unlock // Create a new DB object - db, err = b.createDBObj(req.Storage, role.DBName) + db, err = b.createDBObj(req.Context, req.Storage, role.DBName) if err != nil { unlockFunc() return nil, fmt.Errorf("cound not retrieve db with name: %s, got error: %s", role.DBName, err) @@ -69,7 +69,7 @@ func (b *databaseBackend) secretCredsRenew() framework.OperationFunc { // Make sure we increase the VALID UNTIL endpoint for this user. if expireTime := resp.Secret.ExpirationTime(); !expireTime.IsZero() { - err := db.RenewUser(role.Statements, username, expireTime) + err := db.RenewUser(req.Context, role.Statements, username, expireTime) // Unlock unlockFunc() if err != nil { @@ -119,14 +119,14 @@ func (b *databaseBackend) secretCredsRevoke() framework.OperationFunc { unlockFunc = b.Unlock // Create a new DB object - db, err = b.createDBObj(req.Storage, role.DBName) + db, err = b.createDBObj(req.Context, req.Storage, role.DBName) if err != nil { unlockFunc() return nil, fmt.Errorf("cound not retrieve db with name: %s, got error: %s", role.DBName, err) } } - err = db.RevokeUser(role.Statements, username) + err = db.RevokeUser(req.Context, role.Statements, username) // Unlock unlockFunc() if err != nil { diff --git a/plugins/database/cassandra/cassandra.go b/plugins/database/cassandra/cassandra.go index c0b5fd5d4254..3ed6f237aa9c 100644 --- a/plugins/database/cassandra/cassandra.go +++ b/plugins/database/cassandra/cassandra.go @@ -1,6 +1,7 @@ package cassandra import ( + "context" "strings" "time" @@ -21,6 +22,8 @@ const ( cassandraTypeName = "cassandra" ) +var _ dbplugin.Database = &Cassandra{} + // Cassandra is an implementation of Database interface type Cassandra struct { connutil.ConnectionProducer @@ -75,7 +78,7 @@ func (c *Cassandra) getConnection() (*gocql.Session, error) { // CreateUser generates the username/password on the underlying Cassandra secret backend as instructed by // the CreationStatement provided. -func (c *Cassandra) CreateUser(statements dbplugin.Statements, usernameConfig dbplugin.UsernameConfig, expiration time.Time) (username string, password string, err error) { +func (c *Cassandra) CreateUser(ctx context.Context, statements dbplugin.Statements, usernameConfig dbplugin.UsernameConfig, expiration time.Time) (username string, password string, err error) { // Grab the lock c.Lock() defer c.Unlock() @@ -138,13 +141,13 @@ func (c *Cassandra) CreateUser(statements dbplugin.Statements, usernameConfig db } // RenewUser is not supported on Cassandra, so this is a no-op. -func (c *Cassandra) RenewUser(statements dbplugin.Statements, username string, expiration time.Time) error { +func (c *Cassandra) RenewUser(ctx context.Context, statements dbplugin.Statements, username string, expiration time.Time) error { // NOOP return nil } // RevokeUser attempts to drop the specified user. -func (c *Cassandra) RevokeUser(statements dbplugin.Statements, username string) error { +func (c *Cassandra) RevokeUser(ctx context.Context, statements dbplugin.Statements, username string) error { // Grab the lock c.Lock() defer c.Unlock() diff --git a/plugins/database/cassandra/connection_producer.go b/plugins/database/cassandra/connection_producer.go index 45d46518b6d0..64f2e9ac1202 100644 --- a/plugins/database/cassandra/connection_producer.go +++ b/plugins/database/cassandra/connection_producer.go @@ -1,6 +1,7 @@ package cassandra import ( + "context" "crypto/tls" "fmt" "strings" @@ -43,7 +44,7 @@ type cassandraConnectionProducer struct { sync.Mutex } -func (c *cassandraConnectionProducer) Initialize(conf map[string]interface{}, verifyConnection bool) error { +func (c *cassandraConnectionProducer) Initialize(ctx context.Context, conf map[string]interface{}, verifyConnection bool) error { c.Lock() defer c.Unlock() diff --git a/plugins/database/hana/hana.go b/plugins/database/hana/hana.go index aa2b53d65084..35d7a7b89cf7 100644 --- a/plugins/database/hana/hana.go +++ b/plugins/database/hana/hana.go @@ -1,6 +1,7 @@ package hana import ( + "context" "database/sql" "fmt" "strings" @@ -26,6 +27,8 @@ type HANA struct { credsutil.CredentialsProducer } +var _ dbplugin.Database = &HANA{} + // New implements builtinplugins.BuiltinFactory func New() (interface{}, error) { connProducer := &connutil.SQLConnectionProducer{} @@ -74,7 +77,7 @@ func (h *HANA) getConnection() (*sql.DB, error) { // CreateUser generates the username/password on the underlying HANA secret backend // as instructed by the CreationStatement provided. -func (h *HANA) CreateUser(statements dbplugin.Statements, usernameConfig dbplugin.UsernameConfig, expiration time.Time) (username string, password string, err error) { +func (h *HANA) CreateUser(ctx context.Context, statements dbplugin.Statements, usernameConfig dbplugin.UsernameConfig, expiration time.Time) (username string, password string, err error) { // Grab the lock h.Lock() defer h.Unlock() @@ -153,7 +156,7 @@ func (h *HANA) CreateUser(statements dbplugin.Statements, usernameConfig dbplugi } // Renewing hana user just means altering user's valid until property -func (h *HANA) RenewUser(statements dbplugin.Statements, username string, expiration time.Time) error { +func (h *HANA) RenewUser(ctx context.Context, statements dbplugin.Statements, username string, expiration time.Time) error { // Get connection db, err := h.getConnection() if err != nil { @@ -193,7 +196,7 @@ func (h *HANA) RenewUser(statements dbplugin.Statements, username string, expira } // Revoking hana user will deactivate user and try to perform a soft drop -func (h *HANA) RevokeUser(statements dbplugin.Statements, username string) error { +func (h *HANA) RevokeUser(ctx context.Context, statements dbplugin.Statements, username string) error { // default revoke will be a soft drop on user if statements.RevocationStatements == "" { return h.revokeUserDefault(username) diff --git a/plugins/database/mongodb/connection_producer.go b/plugins/database/mongodb/connection_producer.go index f802dc35e5aa..9d47ce5b0d90 100644 --- a/plugins/database/mongodb/connection_producer.go +++ b/plugins/database/mongodb/connection_producer.go @@ -1,6 +1,7 @@ package mongodb import ( + "context" "crypto/tls" "errors" "fmt" @@ -29,7 +30,7 @@ type mongoDBConnectionProducer struct { } // Initialize parses connection configuration. -func (c *mongoDBConnectionProducer) Initialize(conf map[string]interface{}, verifyConnection bool) error { +func (c *mongoDBConnectionProducer) Initialize(ctx context.Context, conf map[string]interface{}, verifyConnection bool) error { c.Lock() defer c.Unlock() diff --git a/plugins/database/mongodb/mongodb.go b/plugins/database/mongodb/mongodb.go index 52671dae2f5c..4f4c10560b51 100644 --- a/plugins/database/mongodb/mongodb.go +++ b/plugins/database/mongodb/mongodb.go @@ -1,6 +1,7 @@ package mongodb import ( + "context" "io" "strings" "time" @@ -27,6 +28,8 @@ type MongoDB struct { credsutil.CredentialsProducer } +var _ dbplugin.Database = &MongoDB{} + // New returns a new MongoDB instance func New() (interface{}, error) { connProducer := &mongoDBConnectionProducer{} @@ -80,7 +83,7 @@ func (m *MongoDB) getConnection() (*mgo.Session, error) { // // JSON Example: // { "db": "admin", "roles": [{ "role": "readWrite" }, {"role": "read", "db": "foo"}] } -func (m *MongoDB) CreateUser(statements dbplugin.Statements, usernameConfig dbplugin.UsernameConfig, expiration time.Time) (username string, password string, err error) { +func (m *MongoDB) CreateUser(ctx context.Context, statements dbplugin.Statements, usernameConfig dbplugin.UsernameConfig, expiration time.Time) (username string, password string, err error) { // Grab the lock m.Lock() defer m.Unlock() @@ -149,14 +152,14 @@ func (m *MongoDB) CreateUser(statements dbplugin.Statements, usernameConfig dbpl } // RenewUser is not supported on MongoDB, so this is a no-op. -func (m *MongoDB) RenewUser(statements dbplugin.Statements, username string, expiration time.Time) error { +func (m *MongoDB) RenewUser(ctx context.Context, statements dbplugin.Statements, username string, expiration time.Time) error { // NOOP return nil } // RevokeUser drops the specified user from the authentication databse. If none is provided // in the revocation statement, the default "admin" authentication database will be assumed. -func (m *MongoDB) RevokeUser(statements dbplugin.Statements, username string) error { +func (m *MongoDB) RevokeUser(ctx context.Context, statements dbplugin.Statements, username string) error { session, err := m.getConnection() if err != nil { return err diff --git a/plugins/database/mssql/mssql.go b/plugins/database/mssql/mssql.go index 7b920c8c991f..22579f3b77d2 100644 --- a/plugins/database/mssql/mssql.go +++ b/plugins/database/mssql/mssql.go @@ -1,6 +1,7 @@ package mssql import ( + "context" "database/sql" "fmt" "strings" @@ -18,6 +19,8 @@ import ( const msSQLTypeName = "mssql" +var _ dbplugin.Database = &MSSQL{} + // MSSQL is an implementation of Database interface type MSSQL struct { connutil.ConnectionProducer @@ -71,7 +74,7 @@ func (m *MSSQL) getConnection() (*sql.DB, error) { // CreateUser generates the username/password on the underlying MSSQL secret backend as instructed by // the CreationStatement provided. -func (m *MSSQL) CreateUser(statements dbplugin.Statements, usernameConfig dbplugin.UsernameConfig, expiration time.Time) (username string, password string, err error) { +func (m *MSSQL) CreateUser(ctx context.Context, statements dbplugin.Statements, usernameConfig dbplugin.UsernameConfig, expiration time.Time) (username string, password string, err error) { // Grab the lock m.Lock() defer m.Unlock() @@ -138,7 +141,7 @@ func (m *MSSQL) CreateUser(statements dbplugin.Statements, usernameConfig dbplug } // RenewUser is not supported on MSSQL, so this is a no-op. -func (m *MSSQL) RenewUser(statements dbplugin.Statements, username string, expiration time.Time) error { +func (m *MSSQL) RenewUser(ctx context.Context, statements dbplugin.Statements, username string, expiration time.Time) error { // NOOP return nil } @@ -146,7 +149,7 @@ func (m *MSSQL) RenewUser(statements dbplugin.Statements, username string, expir // RevokeUser attempts to drop the specified user. It will first attempt to disable login, // then kill pending connections from that user, and finally drop the user and login from the // database instance. -func (m *MSSQL) RevokeUser(statements dbplugin.Statements, username string) error { +func (m *MSSQL) RevokeUser(ctx context.Context, statements dbplugin.Statements, username string) error { if statements.RevocationStatements == "" { return m.revokeUserDefault(username) } diff --git a/plugins/database/mysql/mysql.go b/plugins/database/mysql/mysql.go index 87289274e0ee..400991a00b29 100644 --- a/plugins/database/mysql/mysql.go +++ b/plugins/database/mysql/mysql.go @@ -1,6 +1,7 @@ package mysql import ( + "context" "database/sql" "strings" "time" @@ -30,6 +31,8 @@ var ( LegacyUsernameLen int = 16 ) +var _ dbplugin.Database = &MySQL{} + type MySQL struct { connutil.ConnectionProducer credsutil.CredentialsProducer @@ -97,7 +100,7 @@ func (m *MySQL) getConnection() (*sql.DB, error) { return db.(*sql.DB), nil } -func (m *MySQL) CreateUser(statements dbplugin.Statements, usernameConfig dbplugin.UsernameConfig, expiration time.Time) (username string, password string, err error) { +func (m *MySQL) CreateUser(ctx context.Context, statements dbplugin.Statements, usernameConfig dbplugin.UsernameConfig, expiration time.Time) (username string, password string, err error) { // Grab the lock m.Lock() defer m.Unlock() @@ -179,11 +182,11 @@ func (m *MySQL) CreateUser(statements dbplugin.Statements, usernameConfig dbplug } // NOOP -func (m *MySQL) RenewUser(statements dbplugin.Statements, username string, expiration time.Time) error { +func (m *MySQL) RenewUser(ctx context.Context, statements dbplugin.Statements, username string, expiration time.Time) error { return nil } -func (m *MySQL) RevokeUser(statements dbplugin.Statements, username string) error { +func (m *MySQL) RevokeUser(ctx context.Context, statements dbplugin.Statements, username string) error { // Grab the read lock m.Lock() defer m.Unlock() diff --git a/plugins/database/postgresql/postgresql.go b/plugins/database/postgresql/postgresql.go index 93fa8a85425d..0955f69c9d89 100644 --- a/plugins/database/postgresql/postgresql.go +++ b/plugins/database/postgresql/postgresql.go @@ -1,6 +1,7 @@ package postgresql import ( + "context" "database/sql" "fmt" "strings" @@ -24,6 +25,8 @@ ALTER ROLE "{{name}}" VALID UNTIL '{{expiration}}'; ` ) +var _ dbplugin.Database = &PostgreSQL{} + // New implements builtinplugins.BuiltinFactory func New() (interface{}, error) { connProducer := &connutil.SQLConnectionProducer{} @@ -74,7 +77,7 @@ func (p *PostgreSQL) getConnection() (*sql.DB, error) { return db.(*sql.DB), nil } -func (p *PostgreSQL) CreateUser(statements dbplugin.Statements, usernameConfig dbplugin.UsernameConfig, expiration time.Time) (username string, password string, err error) { +func (p *PostgreSQL) CreateUser(ctx context.Context, statements dbplugin.Statements, usernameConfig dbplugin.UsernameConfig, expiration time.Time) (username string, password string, err error) { if statements.CreationStatements == "" { return "", "", dbutil.ErrEmptyCreationStatement } @@ -148,7 +151,7 @@ func (p *PostgreSQL) CreateUser(statements dbplugin.Statements, usernameConfig d return username, password, nil } -func (p *PostgreSQL) RenewUser(statements dbplugin.Statements, username string, expiration time.Time) error { +func (p *PostgreSQL) RenewUser(ctx context.Context, statements dbplugin.Statements, username string, expiration time.Time) error { p.Lock() defer p.Unlock() @@ -201,7 +204,7 @@ func (p *PostgreSQL) RenewUser(statements dbplugin.Statements, username string, return nil } -func (p *PostgreSQL) RevokeUser(statements dbplugin.Statements, username string) error { +func (p *PostgreSQL) RevokeUser(ctx context.Context, statements dbplugin.Statements, username string) error { // Grab the lock p.Lock() defer p.Unlock() diff --git a/plugins/helper/database/connutil/connutil.go b/plugins/helper/database/connutil/connutil.go index d36d5719d6a8..0177ecd18e59 100644 --- a/plugins/helper/database/connutil/connutil.go +++ b/plugins/helper/database/connutil/connutil.go @@ -1,6 +1,7 @@ package connutil import ( + "context" "errors" "sync" ) @@ -14,7 +15,7 @@ var ( // connections and is used in all the builtin database types. type ConnectionProducer interface { Close() error - Initialize(map[string]interface{}, bool) error + Initialize(context.Context, map[string]interface{}, bool) error Connection() (interface{}, error) sync.Locker diff --git a/plugins/helper/database/connutil/sql.go b/plugins/helper/database/connutil/sql.go index c325cbc187e0..71c070919bd4 100644 --- a/plugins/helper/database/connutil/sql.go +++ b/plugins/helper/database/connutil/sql.go @@ -1,6 +1,7 @@ package connutil import ( + "context" "database/sql" "fmt" "strings" @@ -25,7 +26,7 @@ type SQLConnectionProducer struct { sync.Mutex } -func (c *SQLConnectionProducer) Initialize(conf map[string]interface{}, verifyConnection bool) error { +func (c *SQLConnectionProducer) Initialize(ctx context.Context, conf map[string]interface{}, verifyConnection bool) error { c.Lock() defer c.Unlock() From f50a199c8eb5656a1486abf9344b631b8c8588c1 Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Wed, 29 Nov 2017 16:15:16 -0800 Subject: [PATCH 4/9] use byte slice instead of string --- builtin/logical/database/dbplugin/client.go | 2 +- .../database/dbplugin/pb/database.pb.go | 76 +++++++++---------- .../database/dbplugin/pb/database.proto | 2 +- builtin/logical/database/dbplugin/server.go | 2 +- 4 files changed, 41 insertions(+), 41 deletions(-) diff --git a/builtin/logical/database/dbplugin/client.go b/builtin/logical/database/dbplugin/client.go index 217f885d6669..6ce2abfb58ae 100644 --- a/builtin/logical/database/dbplugin/client.go +++ b/builtin/logical/database/dbplugin/client.go @@ -154,7 +154,7 @@ func (c *gRPCClient) Initialize(ctx context.Context, config map[string]interface } _, err = c.client.Initialize(ctx, &pb.InitializeRequest{ - Config: string(configRaw[:]), + Config: configRaw, VerifyConnection: verifyConnection, }) diff --git a/builtin/logical/database/dbplugin/pb/database.pb.go b/builtin/logical/database/dbplugin/pb/database.pb.go index 0408dab0edec..9c8b9fbad963 100644 --- a/builtin/logical/database/dbplugin/pb/database.pb.go +++ b/builtin/logical/database/dbplugin/pb/database.pb.go @@ -42,7 +42,7 @@ var _ = math.Inf const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type InitializeRequest struct { - Config string `protobuf:"bytes,1,opt,name=config" json:"config,omitempty"` + Config []byte `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` VerifyConnection bool `protobuf:"varint,2,opt,name=verify_connection,json=verifyConnection" json:"verify_connection,omitempty"` } @@ -51,11 +51,11 @@ func (m *InitializeRequest) String() string { return proto.CompactTex func (*InitializeRequest) ProtoMessage() {} func (*InitializeRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } -func (m *InitializeRequest) GetConfig() string { +func (m *InitializeRequest) GetConfig() []byte { if m != nil { return m.Config } - return "" + return nil } func (m *InitializeRequest) GetVerifyConnection() bool { @@ -519,39 +519,39 @@ func init() { } var fileDescriptor0 = []byte{ - // 541 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xcd, 0x6e, 0xd3, 0x40, - 0x10, 0x96, 0xd3, 0xb4, 0x24, 0x53, 0x94, 0x26, 0x4b, 0x5b, 0x55, 0x96, 0x10, 0x91, 0xb9, 0x14, - 0x81, 0x6c, 0xa9, 0xb9, 0xd1, 0x63, 0xca, 0x01, 0x09, 0xe5, 0x60, 0x5a, 0x89, 0x5b, 0xb4, 0x76, - 0x26, 0xd1, 0xaa, 0x9b, 0xdd, 0xc5, 0xbb, 0x4e, 0x09, 0x6f, 0x02, 0xcf, 0xc2, 0x33, 0xf0, 0x4c, - 0x68, 0xd7, 0xf1, 0x5f, 0x72, 0xac, 0xb8, 0xed, 0xcc, 0x7c, 0xdf, 0xcc, 0xe7, 0xf9, 0x31, 0x4c, - 0x92, 0x9c, 0x71, 0xc3, 0x44, 0xc4, 0xe5, 0x8a, 0xa5, 0x94, 0x47, 0x0b, 0x6a, 0x68, 0x42, 0x35, - 0x46, 0x8b, 0x44, 0xf1, 0x7c, 0xc5, 0x44, 0xa4, 0x92, 0xca, 0x19, 0xaa, 0x4c, 0x1a, 0x49, 0x3a, - 0x2a, 0xf1, 0xdf, 0xac, 0xa4, 0x5c, 0x71, 0x8c, 0x9c, 0x27, 0xc9, 0x97, 0x91, 0x61, 0x6b, 0xd4, - 0x86, 0xae, 0x55, 0x01, 0x0a, 0xbe, 0xc1, 0xe8, 0xb3, 0x60, 0x86, 0x51, 0xce, 0x7e, 0x62, 0x8c, - 0xdf, 0x73, 0xd4, 0x86, 0x5c, 0xc2, 0x49, 0x2a, 0xc5, 0x92, 0xad, 0xae, 0xbc, 0xb1, 0x77, 0xdd, - 0x8f, 0x77, 0x16, 0x79, 0x0f, 0xa3, 0x0d, 0x66, 0x6c, 0xb9, 0x9d, 0xa7, 0x52, 0x08, 0x4c, 0x0d, - 0x93, 0xe2, 0xaa, 0x33, 0xf6, 0xae, 0x7b, 0xf1, 0xb0, 0x08, 0x4c, 0x2b, 0x7f, 0xf0, 0xc7, 0x83, - 0xd1, 0x34, 0x43, 0x6a, 0xf0, 0x41, 0x63, 0x56, 0xa6, 0x0e, 0x01, 0xb4, 0xa1, 0x06, 0xd7, 0x28, - 0x8c, 0x76, 0xe9, 0x4f, 0x6f, 0x06, 0xa1, 0x4a, 0xc2, 0xaf, 0x95, 0x37, 0x6e, 0x20, 0xc8, 0x2d, - 0x9c, 0xe5, 0x1a, 0x33, 0x41, 0xd7, 0x38, 0xdf, 0x69, 0xea, 0x38, 0x12, 0xb1, 0xa4, 0x87, 0x5d, - 0x68, 0xea, 0x22, 0xf1, 0x20, 0x6f, 0xd9, 0xe4, 0x23, 0x00, 0xfe, 0x50, 0x2c, 0xa3, 0x4e, 0xe8, - 0x91, 0xe3, 0xf9, 0x61, 0xd1, 0x92, 0xb0, 0x6c, 0x49, 0x78, 0x5f, 0xb6, 0x24, 0x6e, 0xa0, 0x83, - 0xdf, 0x1e, 0x0c, 0x63, 0x14, 0xf8, 0xf4, 0x1c, 0xf5, 0x3e, 0xf4, 0x4a, 0x49, 0x4e, 0x76, 0x3f, - 0xae, 0xec, 0x67, 0x89, 0x9b, 0xc3, 0x28, 0xc6, 0x8d, 0x7c, 0xc4, 0xff, 0x24, 0x2e, 0xf8, 0xeb, - 0x01, 0xd4, 0x34, 0x12, 0xc1, 0xab, 0xd4, 0x8e, 0x92, 0x49, 0x31, 0xdf, 0xab, 0xd1, 0x8f, 0x49, - 0x19, 0x6a, 0x10, 0x26, 0x70, 0x91, 0xe1, 0x46, 0xa6, 0x07, 0x94, 0xa2, 0xd0, 0x79, 0x1d, 0x6c, - 0x57, 0xc9, 0x24, 0xe7, 0x09, 0x4d, 0x1f, 0x9b, 0x94, 0xa3, 0xa2, 0x4a, 0x19, 0x6a, 0x10, 0xde, - 0xc1, 0x30, 0xb3, 0x23, 0x6a, 0xa2, 0xbb, 0x0e, 0x7d, 0xe6, 0xfc, 0x35, 0x34, 0x98, 0xc1, 0xa0, - 0xbd, 0x2c, 0x64, 0x0c, 0xa7, 0x77, 0x4c, 0x2b, 0x4e, 0xb7, 0x33, 0xdb, 0x81, 0xe2, 0x5b, 0x9a, - 0x2e, 0xdb, 0xa0, 0x58, 0x72, 0x9c, 0x35, 0x1a, 0x54, 0xda, 0xc1, 0x17, 0x20, 0xcd, 0xe5, 0xd6, - 0x4a, 0x0a, 0x8d, 0xad, 0x96, 0x7a, 0x7b, 0xf3, 0xf6, 0xa1, 0xa7, 0xa8, 0xd6, 0x4f, 0x32, 0x5b, - 0x94, 0xd9, 0x4a, 0x3b, 0x08, 0xe0, 0xe5, 0xfd, 0x56, 0x61, 0x95, 0x87, 0x40, 0xd7, 0x6c, 0x55, - 0x99, 0xc3, 0xbd, 0x83, 0x17, 0x70, 0xfc, 0x69, 0xad, 0xcc, 0xf6, 0xe6, 0x57, 0x07, 0x7a, 0x77, - 0xbb, 0x53, 0x27, 0x6f, 0xa1, 0x6b, 0x99, 0xa4, 0x6f, 0x07, 0xed, 0xe2, 0xfe, 0xd0, 0x3e, 0x5b, - 0xe9, 0x6e, 0x01, 0x6a, 0xb1, 0xe4, 0xc2, 0xc6, 0x0f, 0x2e, 0xd3, 0xbf, 0xdc, 0x77, 0xef, 0xc8, - 0x1f, 0xa0, 0x5f, 0xdd, 0x01, 0x39, 0xb7, 0xa0, 0xfd, 0xb3, 0xf0, 0xeb, 0xe2, 0x76, 0x09, 0xeb, - 0xcd, 0x2c, 0x4a, 0x1d, 0x6c, 0xea, 0x1e, 0xbe, 0xfe, 0xff, 0x14, 0xf8, 0x83, 0xff, 0x51, 0x13, - 0xff, 0x1a, 0x8e, 0xa7, 0x5c, 0xea, 0xd6, 0x07, 0xd7, 0xcf, 0xe4, 0xc4, 0x1d, 0xce, 0xe4, 0x5f, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x89, 0x25, 0x43, 0x3e, 0x31, 0x05, 0x00, 0x00, + // 542 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0x4d, 0x6e, 0xdb, 0x3c, + 0x10, 0x85, 0x1c, 0x27, 0x9f, 0x3d, 0x09, 0x1c, 0x9b, 0x5f, 0x12, 0x04, 0x02, 0x8a, 0x1a, 0xea, + 0x26, 0x45, 0x0b, 0x09, 0x88, 0x77, 0xcd, 0xd2, 0xe9, 0xa2, 0x40, 0xe1, 0x85, 0x9a, 0x00, 0xdd, + 0x19, 0x94, 0x3c, 0x36, 0x88, 0xd0, 0x24, 0x2b, 0x52, 0x4e, 0xdd, 0x9b, 0xb4, 0x67, 0xe9, 0x19, + 0x7a, 0xa6, 0x82, 0x94, 0xf5, 0x67, 0x2f, 0x83, 0xee, 0x38, 0x33, 0xef, 0xcd, 0x3c, 0xcd, 0x8f, + 0x60, 0x92, 0xe4, 0x8c, 0x1b, 0x26, 0x22, 0x2e, 0x57, 0x2c, 0xa5, 0x3c, 0x5a, 0x50, 0x43, 0x13, + 0xaa, 0x31, 0x5a, 0x24, 0x8a, 0xe7, 0x2b, 0x26, 0x22, 0x95, 0x54, 0xce, 0x50, 0x65, 0xd2, 0x48, + 0xd2, 0x51, 0x89, 0xff, 0x7a, 0x25, 0xe5, 0x8a, 0x63, 0xe4, 0x3c, 0x49, 0xbe, 0x8c, 0x0c, 0x5b, + 0xa3, 0x36, 0x74, 0xad, 0x0a, 0x50, 0xf0, 0x15, 0x46, 0x9f, 0x04, 0x33, 0x8c, 0x72, 0xf6, 0x03, + 0x63, 0xfc, 0x96, 0xa3, 0x36, 0xe4, 0x0a, 0x4e, 0x52, 0x29, 0x96, 0x6c, 0x75, 0xed, 0x8d, 0xbd, + 0x9b, 0xb3, 0x78, 0x67, 0x91, 0x77, 0x30, 0xda, 0x60, 0xc6, 0x96, 0xdb, 0x79, 0x2a, 0x85, 0xc0, + 0xd4, 0x30, 0x29, 0xae, 0x3b, 0x63, 0xef, 0xa6, 0x17, 0x0f, 0x8b, 0xc0, 0xb4, 0xf2, 0x07, 0xbf, + 0x3d, 0x18, 0x4d, 0x33, 0xa4, 0x06, 0x1f, 0x35, 0x66, 0x65, 0xea, 0x10, 0x40, 0x1b, 0x6a, 0x70, + 0x8d, 0xc2, 0x68, 0x97, 0xfe, 0xf4, 0x76, 0x10, 0xaa, 0x24, 0xfc, 0x52, 0x79, 0xe3, 0x06, 0x82, + 0xdc, 0xc1, 0x79, 0xae, 0x31, 0x13, 0x74, 0x8d, 0xf3, 0x9d, 0xa6, 0x8e, 0x23, 0x11, 0x4b, 0x7a, + 0xdc, 0x85, 0xa6, 0x2e, 0x12, 0x0f, 0xf2, 0x96, 0x4d, 0x3e, 0x00, 0xe0, 0x77, 0xc5, 0x32, 0xea, + 0x84, 0x1e, 0x39, 0x9e, 0x1f, 0x16, 0x2d, 0x09, 0xcb, 0x96, 0x84, 0x0f, 0x65, 0x4b, 0xe2, 0x06, + 0x3a, 0xf8, 0xe5, 0xc1, 0x30, 0x46, 0x81, 0xcf, 0x2f, 0x51, 0xef, 0x43, 0xaf, 0x94, 0xe4, 0x64, + 0xf7, 0xe3, 0xca, 0x7e, 0x91, 0xb8, 0x39, 0x8c, 0x62, 0xdc, 0xc8, 0x27, 0xfc, 0x47, 0xe2, 0x82, + 0x3f, 0x1e, 0x40, 0x4d, 0x23, 0x11, 0xfc, 0x9f, 0xda, 0x51, 0x32, 0x29, 0xe6, 0x7b, 0x35, 0xfa, + 0x31, 0x29, 0x43, 0x0d, 0xc2, 0x04, 0x2e, 0x33, 0xdc, 0xc8, 0xf4, 0x80, 0x52, 0x14, 0xba, 0xa8, + 0x83, 0xed, 0x2a, 0x99, 0xe4, 0x3c, 0xa1, 0xe9, 0x53, 0x93, 0x72, 0x54, 0x54, 0x29, 0x43, 0x0d, + 0xc2, 0x5b, 0x18, 0x66, 0x76, 0x44, 0x4d, 0x74, 0xd7, 0xa1, 0xcf, 0x9d, 0xbf, 0x86, 0x06, 0x33, + 0x18, 0xb4, 0x97, 0x85, 0x8c, 0xe1, 0xf4, 0x9e, 0x69, 0xc5, 0xe9, 0x76, 0x66, 0x3b, 0x50, 0x7c, + 0x4b, 0xd3, 0x65, 0x1b, 0x14, 0x4b, 0x8e, 0xb3, 0x46, 0x83, 0x4a, 0x3b, 0xf8, 0x0c, 0xa4, 0xb9, + 0xdc, 0x5a, 0x49, 0xa1, 0xb1, 0xd5, 0x52, 0x6f, 0x6f, 0xde, 0x3e, 0xf4, 0x14, 0xd5, 0xfa, 0x59, + 0x66, 0x8b, 0x32, 0x5b, 0x69, 0x07, 0x01, 0x9c, 0x3d, 0x6c, 0x15, 0x56, 0x79, 0x08, 0x74, 0xcd, + 0x56, 0x95, 0x39, 0xdc, 0x3b, 0xf8, 0x0f, 0x8e, 0x3f, 0xae, 0x95, 0xd9, 0xde, 0xfe, 0xec, 0x40, + 0xef, 0x7e, 0x77, 0xea, 0xe4, 0x0d, 0x74, 0x2d, 0x93, 0xf4, 0xed, 0xa0, 0x5d, 0xdc, 0x1f, 0xda, + 0x67, 0x2b, 0xdd, 0x1d, 0x40, 0x2d, 0x96, 0x5c, 0xda, 0xf8, 0xc1, 0x65, 0xfa, 0x57, 0xfb, 0xee, + 0x1d, 0xf9, 0x3d, 0xf4, 0xab, 0x3b, 0x20, 0x17, 0x16, 0xb4, 0x7f, 0x16, 0x7e, 0x5d, 0xdc, 0x2e, + 0x61, 0xbd, 0x99, 0x45, 0xa9, 0x83, 0x4d, 0xdd, 0xc3, 0xd7, 0xff, 0x9f, 0x02, 0x7f, 0xf0, 0x3f, + 0x6a, 0xe2, 0x5f, 0xc1, 0xf1, 0x94, 0x4b, 0xdd, 0xfa, 0xe0, 0xfa, 0x99, 0x9c, 0xb8, 0xc3, 0x99, + 0xfc, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xe6, 0xbc, 0xdd, 0x88, 0x31, 0x05, 0x00, 0x00, } diff --git a/builtin/logical/database/dbplugin/pb/database.proto b/builtin/logical/database/dbplugin/pb/database.proto index 185128f8cee2..75fb28619aa5 100644 --- a/builtin/logical/database/dbplugin/pb/database.proto +++ b/builtin/logical/database/dbplugin/pb/database.proto @@ -4,7 +4,7 @@ package pb; import "google/protobuf/timestamp.proto"; message InitializeRequest { - string config = 1; + bytes config = 1; bool verify_connection = 2; } diff --git a/builtin/logical/database/dbplugin/server.go b/builtin/logical/database/dbplugin/server.go index a1286345496e..5a079ac9cfc0 100644 --- a/builtin/logical/database/dbplugin/server.go +++ b/builtin/logical/database/dbplugin/server.go @@ -105,7 +105,7 @@ func (s *gRPCServer) RevokeUser(ctx context.Context, req *pb.RevokeUserRequest) func (s *gRPCServer) Initialize(ctx context.Context, req *pb.InitializeRequest) (*pb.Empty, error) { config := map[string]interface{}{} - err := json.Unmarshal([]byte(req.Config), config) + err := json.Unmarshal(req.Config, config) if err != nil { return nil, err } From cc6de6a58b0167a056ebdffbefd96a7ca3ec16b2 Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Wed, 29 Nov 2017 17:43:09 -0800 Subject: [PATCH 5/9] Context all the things --- builtin/logical/database/dbplugin/client.go | 2 ++ builtin/logical/database/dbplugin/server.go | 2 +- helper/pluginutil/runner.go | 4 ++++ logical/request.go | 15 +++++++------- plugins/database/cassandra/cassandra.go | 8 ++++---- .../database/cassandra/connection_producer.go | 4 ++-- plugins/database/hana/hana.go | 16 +++++++-------- .../database/mongodb/connection_producer.go | 4 ++-- plugins/database/mongodb/mongodb.go | 12 +++++------ plugins/database/mssql/mssql.go | 14 ++++++------- plugins/database/mysql/mysql.go | 20 +++++++++---------- plugins/database/postgresql/postgresql.go | 20 +++++++++---------- plugins/helper/database/connutil/connutil.go | 2 +- plugins/helper/database/connutil/sql.go | 8 ++++---- vault/expiration.go | 10 +++++----- 15 files changed, 74 insertions(+), 67 deletions(-) diff --git a/builtin/logical/database/dbplugin/client.go b/builtin/logical/database/dbplugin/client.go index 6ce2abfb58ae..fcca1a9803b6 100644 --- a/builtin/logical/database/dbplugin/client.go +++ b/builtin/logical/database/dbplugin/client.go @@ -126,6 +126,7 @@ func (c *gRPCClient) RenewUser(ctx context.Context, statements Statements, usern _, err = c.client.RenewUser(ctx, &pb.RenewUserRequest{ Statements: s, + Username: username, Expiration: t, }) @@ -142,6 +143,7 @@ func (c *gRPCClient) RevokeUser(ctx context.Context, statements Statements, user _, err := c.client.RevokeUser(ctx, &pb.RevokeUserRequest{ Statements: s, + Username: username, }) return err diff --git a/builtin/logical/database/dbplugin/server.go b/builtin/logical/database/dbplugin/server.go index 5a079ac9cfc0..160310fbd044 100644 --- a/builtin/logical/database/dbplugin/server.go +++ b/builtin/logical/database/dbplugin/server.go @@ -105,7 +105,7 @@ func (s *gRPCServer) RevokeUser(ctx context.Context, req *pb.RevokeUserRequest) func (s *gRPCServer) Initialize(ctx context.Context, req *pb.InitializeRequest) (*pb.Empty, error) { config := map[string]interface{}{} - err := json.Unmarshal(req.Config, config) + err := json.Unmarshal(req.Config, &config) if err != nil { return nil, err } diff --git a/helper/pluginutil/runner.go b/helper/pluginutil/runner.go index 2047651ed2af..bd9986e2db87 100644 --- a/helper/pluginutil/runner.go +++ b/helper/pluginutil/runner.go @@ -119,6 +119,10 @@ func (r *PluginRunner) runCommon(wrapper RunnerUtil, pluginMap map[string]plugin SecureConfig: secureConfig, TLSConfig: clientTLSConfig, Logger: namedLogger, + AllowedProtocols: []plugin.Protocol{ + plugin.ProtocolNetRPC, + plugin.ProtocolGRPC, + }, } client := plugin.NewClient(clientConfig) diff --git a/logical/request.go b/logical/request.go index 1808840a4664..109d9952de6b 100644 --- a/logical/request.go +++ b/logical/request.go @@ -205,9 +205,9 @@ func (r *Request) SetLastRemoteWAL(last uint64) { } // RenewRequest creates the structure of the renew request. -func RenewRequest( - path string, secret *Secret, data map[string]interface{}) *Request { +func RenewRequest(ctx context.Context, path string, secret *Secret, data map[string]interface{}) *Request { return &Request{ + Context: ctx, Operation: RenewOperation, Path: path, Data: data, @@ -216,9 +216,9 @@ func RenewRequest( } // RenewAuthRequest creates the structure of the renew request for an auth. -func RenewAuthRequest( - path string, auth *Auth, data map[string]interface{}) *Request { +func RenewAuthRequest(ctx context.Context, path string, auth *Auth, data map[string]interface{}) *Request { return &Request{ + Context: ctx, Operation: RenewOperation, Path: path, Data: data, @@ -227,9 +227,9 @@ func RenewAuthRequest( } // RevokeRequest creates the structure of the revoke request. -func RevokeRequest( - path string, secret *Secret, data map[string]interface{}) *Request { +func RevokeRequest(ctx context.Context, path string, secret *Secret, data map[string]interface{}) *Request { return &Request{ + Context: ctx, Operation: RevokeOperation, Path: path, Data: data, @@ -238,8 +238,9 @@ func RevokeRequest( } // RollbackRequest creates the structure of the revoke request. -func RollbackRequest(path string) *Request { +func RollbackRequest(ctx context.Context, path string) *Request { return &Request{ + Context: ctx, Operation: RollbackOperation, Path: path, Data: make(map[string]interface{}), diff --git a/plugins/database/cassandra/cassandra.go b/plugins/database/cassandra/cassandra.go index 3ed6f237aa9c..221784e0fc31 100644 --- a/plugins/database/cassandra/cassandra.go +++ b/plugins/database/cassandra/cassandra.go @@ -67,8 +67,8 @@ func (c *Cassandra) Type() (string, error) { return cassandraTypeName, nil } -func (c *Cassandra) getConnection() (*gocql.Session, error) { - session, err := c.Connection() +func (c *Cassandra) getConnection(ctx context.Context) (*gocql.Session, error) { + session, err := c.Connection(ctx) if err != nil { return nil, err } @@ -84,7 +84,7 @@ func (c *Cassandra) CreateUser(ctx context.Context, statements dbplugin.Statemen defer c.Unlock() // Get the connection - session, err := c.getConnection() + session, err := c.getConnection(ctx) if err != nil { return "", "", err } @@ -152,7 +152,7 @@ func (c *Cassandra) RevokeUser(ctx context.Context, statements dbplugin.Statemen c.Lock() defer c.Unlock() - session, err := c.getConnection() + session, err := c.getConnection(ctx) if err != nil { return err } diff --git a/plugins/database/cassandra/connection_producer.go b/plugins/database/cassandra/connection_producer.go index 64f2e9ac1202..a0879483a665 100644 --- a/plugins/database/cassandra/connection_producer.go +++ b/plugins/database/cassandra/connection_producer.go @@ -107,7 +107,7 @@ func (c *cassandraConnectionProducer) Initialize(ctx context.Context, conf map[s c.Initialized = true if verifyConnection { - if _, err := c.Connection(); err != nil { + if _, err := c.Connection(ctx); err != nil { return fmt.Errorf("error verifying connection: %s", err) } } @@ -115,7 +115,7 @@ func (c *cassandraConnectionProducer) Initialize(ctx context.Context, conf map[s return nil } -func (c *cassandraConnectionProducer) Connection() (interface{}, error) { +func (c *cassandraConnectionProducer) Connection(ctx context.Context) (interface{}, error) { if !c.Initialized { return nil, connutil.ErrNotInitialized } diff --git a/plugins/database/hana/hana.go b/plugins/database/hana/hana.go index 35d7a7b89cf7..c4aaf972ff58 100644 --- a/plugins/database/hana/hana.go +++ b/plugins/database/hana/hana.go @@ -66,8 +66,8 @@ func (h *HANA) Type() (string, error) { return hanaTypeName, nil } -func (h *HANA) getConnection() (*sql.DB, error) { - db, err := h.Connection() +func (h *HANA) getConnection(ctx context.Context) (*sql.DB, error) { + db, err := h.Connection(ctx) if err != nil { return nil, err } @@ -83,7 +83,7 @@ func (h *HANA) CreateUser(ctx context.Context, statements dbplugin.Statements, u defer h.Unlock() // Get the connection - db, err := h.getConnection() + db, err := h.getConnection(ctx) if err != nil { return "", "", err } @@ -158,7 +158,7 @@ func (h *HANA) CreateUser(ctx context.Context, statements dbplugin.Statements, u // Renewing hana user just means altering user's valid until property func (h *HANA) RenewUser(ctx context.Context, statements dbplugin.Statements, username string, expiration time.Time) error { // Get connection - db, err := h.getConnection() + db, err := h.getConnection(ctx) if err != nil { return err } @@ -199,11 +199,11 @@ func (h *HANA) RenewUser(ctx context.Context, statements dbplugin.Statements, us func (h *HANA) RevokeUser(ctx context.Context, statements dbplugin.Statements, username string) error { // default revoke will be a soft drop on user if statements.RevocationStatements == "" { - return h.revokeUserDefault(username) + return h.revokeUserDefault(ctx, username) } // Get connection - db, err := h.getConnection() + db, err := h.getConnection(ctx) if err != nil { return err } @@ -242,9 +242,9 @@ func (h *HANA) RevokeUser(ctx context.Context, statements dbplugin.Statements, u return nil } -func (h *HANA) revokeUserDefault(username string) error { +func (h *HANA) revokeUserDefault(ctx context.Context, username string) error { // Get connection - db, err := h.getConnection() + db, err := h.getConnection(ctx) if err != nil { return err } diff --git a/plugins/database/mongodb/connection_producer.go b/plugins/database/mongodb/connection_producer.go index 9d47ce5b0d90..9826eecab22a 100644 --- a/plugins/database/mongodb/connection_producer.go +++ b/plugins/database/mongodb/connection_producer.go @@ -48,7 +48,7 @@ func (c *mongoDBConnectionProducer) Initialize(ctx context.Context, conf map[str c.Initialized = true if verifyConnection { - if _, err := c.Connection(); err != nil { + if _, err := c.Connection(ctx); err != nil { return fmt.Errorf("error verifying connection: %s", err) } @@ -61,7 +61,7 @@ func (c *mongoDBConnectionProducer) Initialize(ctx context.Context, conf map[str } // Connection creates a database connection. -func (c *mongoDBConnectionProducer) Connection() (interface{}, error) { +func (c *mongoDBConnectionProducer) Connection(ctx context.Context) (interface{}, error) { if !c.Initialized { return nil, connutil.ErrNotInitialized } diff --git a/plugins/database/mongodb/mongodb.go b/plugins/database/mongodb/mongodb.go index 4f4c10560b51..8b2ee802b0f2 100644 --- a/plugins/database/mongodb/mongodb.go +++ b/plugins/database/mongodb/mongodb.go @@ -66,8 +66,8 @@ func (m *MongoDB) Type() (string, error) { return mongoDBTypeName, nil } -func (m *MongoDB) getConnection() (*mgo.Session, error) { - session, err := m.Connection() +func (m *MongoDB) getConnection(ctx context.Context) (*mgo.Session, error) { + session, err := m.Connection(ctx) if err != nil { return nil, err } @@ -92,7 +92,7 @@ func (m *MongoDB) CreateUser(ctx context.Context, statements dbplugin.Statements return "", "", dbutil.ErrEmptyCreationStatement } - session, err := m.getConnection() + session, err := m.getConnection(ctx) if err != nil { return "", "", err } @@ -136,7 +136,7 @@ func (m *MongoDB) CreateUser(ctx context.Context, statements dbplugin.Statements if err := m.ConnectionProducer.Close(); err != nil { return "", "", errwrap.Wrapf("error closing EOF'd mongo connection: {{err}}", err) } - session, err := m.getConnection() + session, err := m.getConnection(ctx) if err != nil { return "", "", err } @@ -160,7 +160,7 @@ func (m *MongoDB) RenewUser(ctx context.Context, statements dbplugin.Statements, // RevokeUser drops the specified user from the authentication databse. If none is provided // in the revocation statement, the default "admin" authentication database will be assumed. func (m *MongoDB) RevokeUser(ctx context.Context, statements dbplugin.Statements, username string) error { - session, err := m.getConnection() + session, err := m.getConnection(ctx) if err != nil { return err } @@ -191,7 +191,7 @@ func (m *MongoDB) RevokeUser(ctx context.Context, statements dbplugin.Statements if err := m.ConnectionProducer.Close(); err != nil { return errwrap.Wrapf("error closing EOF'd mongo connection: {{err}}", err) } - session, err := m.getConnection() + session, err := m.getConnection(ctx) if err != nil { return err } diff --git a/plugins/database/mssql/mssql.go b/plugins/database/mssql/mssql.go index 22579f3b77d2..d43146c00739 100644 --- a/plugins/database/mssql/mssql.go +++ b/plugins/database/mssql/mssql.go @@ -63,8 +63,8 @@ func (m *MSSQL) Type() (string, error) { return msSQLTypeName, nil } -func (m *MSSQL) getConnection() (*sql.DB, error) { - db, err := m.Connection() +func (m *MSSQL) getConnection(ctx context.Context) (*sql.DB, error) { + db, err := m.Connection(ctx) if err != nil { return nil, err } @@ -80,7 +80,7 @@ func (m *MSSQL) CreateUser(ctx context.Context, statements dbplugin.Statements, defer m.Unlock() // Get the connection - db, err := m.getConnection() + db, err := m.getConnection(ctx) if err != nil { return "", "", err } @@ -151,11 +151,11 @@ func (m *MSSQL) RenewUser(ctx context.Context, statements dbplugin.Statements, u // database instance. func (m *MSSQL) RevokeUser(ctx context.Context, statements dbplugin.Statements, username string) error { if statements.RevocationStatements == "" { - return m.revokeUserDefault(username) + return m.revokeUserDefault(ctx, username) } // Get connection - db, err := m.getConnection() + db, err := m.getConnection(ctx) if err != nil { return err } @@ -194,9 +194,9 @@ func (m *MSSQL) RevokeUser(ctx context.Context, statements dbplugin.Statements, return nil } -func (m *MSSQL) revokeUserDefault(username string) error { +func (m *MSSQL) revokeUserDefault(ctx context.Context, username string) error { // Get connection - db, err := m.getConnection() + db, err := m.getConnection(ctx) if err != nil { return err } diff --git a/plugins/database/mysql/mysql.go b/plugins/database/mysql/mysql.go index 400991a00b29..38c928c35a59 100644 --- a/plugins/database/mysql/mysql.go +++ b/plugins/database/mysql/mysql.go @@ -91,8 +91,8 @@ func (m *MySQL) Type() (string, error) { return mySQLTypeName, nil } -func (m *MySQL) getConnection() (*sql.DB, error) { - db, err := m.Connection() +func (m *MySQL) getConnection(ctx context.Context) (*sql.DB, error) { + db, err := m.Connection(ctx) if err != nil { return nil, err } @@ -106,7 +106,7 @@ func (m *MySQL) CreateUser(ctx context.Context, statements dbplugin.Statements, defer m.Unlock() // Get the connection - db, err := m.getConnection() + db, err := m.getConnection(ctx) if err != nil { return "", "", err } @@ -131,7 +131,7 @@ func (m *MySQL) CreateUser(ctx context.Context, statements dbplugin.Statements, } // Start a transaction - tx, err := db.Begin() + tx, err := db.BeginTx(ctx, nil) if err != nil { return "", "", err } @@ -149,7 +149,7 @@ func (m *MySQL) CreateUser(ctx context.Context, statements dbplugin.Statements, "expiration": expirationStr, }) - stmt, err := tx.Prepare(query) + stmt, err := tx.PrepareContext(ctx, query) if err != nil { // If the error code we get back is Error 1295: This command is not // supported in the prepared statement protocol yet, we will execute @@ -158,7 +158,7 @@ func (m *MySQL) CreateUser(ctx context.Context, statements dbplugin.Statements, // prepare supported commands. If there is no error when running we // will continue to the next statement. if e, ok := err.(*stdmysql.MySQLError); ok && e.Number == 1295 { - _, err = tx.Exec(query) + _, err = tx.ExecContext(ctx, query) if err != nil { return "", "", err } @@ -168,7 +168,7 @@ func (m *MySQL) CreateUser(ctx context.Context, statements dbplugin.Statements, return "", "", err } defer stmt.Close() - if _, err := stmt.Exec(); err != nil { + if _, err := stmt.ExecContext(ctx); err != nil { return "", "", err } } @@ -192,7 +192,7 @@ func (m *MySQL) RevokeUser(ctx context.Context, statements dbplugin.Statements, defer m.Unlock() // Get the connection - db, err := m.getConnection() + db, err := m.getConnection(ctx) if err != nil { return err } @@ -204,7 +204,7 @@ func (m *MySQL) RevokeUser(ctx context.Context, statements dbplugin.Statements, } // Start a transaction - tx, err := db.Begin() + tx, err := db.BeginTx(ctx, nil) if err != nil { return err } @@ -220,7 +220,7 @@ func (m *MySQL) RevokeUser(ctx context.Context, statements dbplugin.Statements, // 1295: This command is not supported in the prepared statement protocol yet // Reference https://mariadb.com/kb/en/mariadb/prepare-statement/ query = strings.Replace(query, "{{name}}", username, -1) - _, err = tx.Exec(query) + _, err = tx.ExecContext(ctx, query) if err != nil { return err } diff --git a/plugins/database/postgresql/postgresql.go b/plugins/database/postgresql/postgresql.go index 0955f69c9d89..0a7c98e918fd 100644 --- a/plugins/database/postgresql/postgresql.go +++ b/plugins/database/postgresql/postgresql.go @@ -68,8 +68,8 @@ func (p *PostgreSQL) Type() (string, error) { return postgreSQLTypeName, nil } -func (p *PostgreSQL) getConnection() (*sql.DB, error) { - db, err := p.Connection() +func (p *PostgreSQL) getConnection(ctx context.Context) (*sql.DB, error) { + db, err := p.Connection(ctx) if err != nil { return nil, err } @@ -102,7 +102,7 @@ func (p *PostgreSQL) CreateUser(ctx context.Context, statements dbplugin.Stateme } // Get the connection - db, err := p.getConnection() + db, err := p.getConnection(ctx) if err != nil { return "", "", err @@ -160,7 +160,7 @@ func (p *PostgreSQL) RenewUser(ctx context.Context, statements dbplugin.Statemen renewStmts = defaultPostgresRenewSQL } - db, err := p.getConnection() + db, err := p.getConnection(ctx) if err != nil { return err } @@ -210,14 +210,14 @@ func (p *PostgreSQL) RevokeUser(ctx context.Context, statements dbplugin.Stateme defer p.Unlock() if statements.RevocationStatements == "" { - return p.defaultRevokeUser(username) + return p.defaultRevokeUser(ctx, username) } - return p.customRevokeUser(username, statements.RevocationStatements) + return p.customRevokeUser(ctx, username, statements.RevocationStatements) } -func (p *PostgreSQL) customRevokeUser(username, revocationStmts string) error { - db, err := p.getConnection() +func (p *PostgreSQL) customRevokeUser(ctx context.Context, username, revocationStmts string) error { + db, err := p.getConnection(ctx) if err != nil { return err } @@ -256,8 +256,8 @@ func (p *PostgreSQL) customRevokeUser(username, revocationStmts string) error { return nil } -func (p *PostgreSQL) defaultRevokeUser(username string) error { - db, err := p.getConnection() +func (p *PostgreSQL) defaultRevokeUser(ctx context.Context, username string) error { + db, err := p.getConnection(ctx) if err != nil { return err } diff --git a/plugins/helper/database/connutil/connutil.go b/plugins/helper/database/connutil/connutil.go index 0177ecd18e59..7cf23c5c3e73 100644 --- a/plugins/helper/database/connutil/connutil.go +++ b/plugins/helper/database/connutil/connutil.go @@ -16,7 +16,7 @@ var ( type ConnectionProducer interface { Close() error Initialize(context.Context, map[string]interface{}, bool) error - Connection() (interface{}, error) + Connection(context.Context) (interface{}, error) sync.Locker } diff --git a/plugins/helper/database/connutil/sql.go b/plugins/helper/database/connutil/sql.go index 71c070919bd4..2e34065d0341 100644 --- a/plugins/helper/database/connutil/sql.go +++ b/plugins/helper/database/connutil/sql.go @@ -63,11 +63,11 @@ func (c *SQLConnectionProducer) Initialize(ctx context.Context, conf map[string] c.Initialized = true if verifyConnection { - if _, err := c.Connection(); err != nil { + if _, err := c.Connection(ctx); err != nil { return fmt.Errorf("error verifying connection: %s", err) } - if err := c.db.Ping(); err != nil { + if err := c.db.PingContext(ctx); err != nil { return fmt.Errorf("error verifying connection: %s", err) } } @@ -75,14 +75,14 @@ func (c *SQLConnectionProducer) Initialize(ctx context.Context, conf map[string] return nil } -func (c *SQLConnectionProducer) Connection() (interface{}, error) { +func (c *SQLConnectionProducer) Connection(ctx context.Context) (interface{}, error) { if !c.Initialized { return nil, ErrNotInitialized } // If we already have a DB, test it and return if c.db != nil { - if err := c.db.Ping(); err == nil { + if err := c.db.PingContext(ctx); err == nil { return c.db, nil } // If the ping was unsuccessful, close it and ignore errors as we'll be diff --git a/vault/expiration.go b/vault/expiration.go index 710fcb8f0b16..2a8049f0721d 100644 --- a/vault/expiration.go +++ b/vault/expiration.go @@ -1,6 +1,7 @@ package vault import ( + "context" "encoding/json" "errors" "fmt" @@ -792,7 +793,7 @@ func (m *ExpirationManager) Register(req *logical.Request, resp *logical.Respons // want to revoke a generated secret (since an error means we may not // be successfully tracking it), remove indexes, and delete the entry. if retErr != nil { - revResp, err := m.router.Route(logical.RevokeRequest(req.Path, resp.Secret, resp.Data)) + revResp, err := m.router.Route(logical.RevokeRequest(context.TODO(), req.Path, resp.Secret, resp.Data)) if err != nil { retErr = multierror.Append(retErr, errwrap.Wrapf("an additional internal error was encountered revoking the newly-generated secret: {{err}}", err)) } else if revResp != nil && revResp.IsError() { @@ -995,8 +996,7 @@ func (m *ExpirationManager) revokeEntry(le *leaseEntry) error { } // Handle standard revocation via backends - resp, err := m.router.Route(logical.RevokeRequest( - le.Path, le.Secret, le.Data)) + resp, err := m.router.Route(logical.RevokeRequest(context.TODO(), le.Path, le.Secret, le.Data)) if err != nil || (resp != nil && resp.IsError()) { return fmt.Errorf("failed to revoke entry: resp:%#v err:%s", resp, err) } @@ -1010,7 +1010,7 @@ func (m *ExpirationManager) renewEntry(le *leaseEntry, increment time.Duration) secret.Increment = increment secret.LeaseID = "" - req := logical.RenewRequest(le.Path, &secret, le.Data) + req := logical.RenewRequest(context.TODO(), le.Path, &secret, le.Data) resp, err := m.router.Route(req) if err != nil || (resp != nil && resp.IsError()) { return nil, fmt.Errorf("failed to renew entry: resp:%#v err:%s", resp, err) @@ -1030,7 +1030,7 @@ func (m *ExpirationManager) renewAuthEntry(req *logical.Request, le *leaseEntry, auth.ClientToken = "" } - authReq := logical.RenewAuthRequest(le.Path, &auth, nil) + authReq := logical.RenewAuthRequest(context.TODO(), le.Path, &auth, nil) authReq.Connection = req.Connection resp, err := m.router.Route(authReq) if err != nil { From bed7cbda4313243b6d7937c2208a8b137fcd31c1 Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Fri, 1 Dec 2017 11:11:34 -0800 Subject: [PATCH 6/9] Move proto messages to the dbplugin package --- Makefile | 2 +- builtin/logical/database/dbplugin/client.go | 60 +++----- .../database/dbplugin/{pb => }/database.pb.go | 129 +++++++++--------- .../database/dbplugin/{pb => }/database.proto | 2 +- builtin/logical/database/dbplugin/plugin.go | 23 +--- builtin/logical/database/dbplugin/server.go | 57 ++------ 6 files changed, 104 insertions(+), 169 deletions(-) rename builtin/logical/database/dbplugin/{pb => }/database.pb.go (75%) rename builtin/logical/database/dbplugin/{pb => }/database.proto (98%) diff --git a/Makefile b/Makefile index 61179b96896b..236947c986f6 100644 --- a/Makefile +++ b/Makefile @@ -83,7 +83,7 @@ proto: protoc -I helper/storagepacker helper/storagepacker/types.proto --go_out=plugins=grpc:helper/storagepacker protoc -I helper/forwarding -I vault -I ../../.. helper/forwarding/types.proto --go_out=plugins=grpc:helper/forwarding protoc -I helper/identity -I ../../.. helper/identity/types.proto --go_out=plugins=grpc:helper/identity - protoc builtin/logical/database/dbplugin/pb/*.proto --go_out=plugins=grpc:. + protoc builtin/logical/database/dbplugin/*.proto --go_out=plugins=grpc:. sed -i -e 's/Idp/IDP/' -e 's/Url/URL/' -e 's/Id/ID/' -e 's/EntityId/EntityID/' -e 's/Api/API/' -e 's/Qr/QR/' -e 's/protobuf:"/sentinel:"" protobuf:"/' helper/identity/types.pb.go helper/storagepacker/types.pb.go fmtcheck: diff --git a/builtin/logical/database/dbplugin/client.go b/builtin/logical/database/dbplugin/client.go index fcca1a9803b6..462d4af717f6 100644 --- a/builtin/logical/database/dbplugin/client.go +++ b/builtin/logical/database/dbplugin/client.go @@ -6,9 +6,10 @@ import ( "sync" "time" + "google.golang.org/grpc" + "github.com/golang/protobuf/ptypes" "github.com/hashicorp/go-plugin" - "github.com/hashicorp/vault/builtin/logical/database/dbplugin/pb" "github.com/hashicorp/vault/helper/pluginutil" log "github.com/mgutz/logxi/v1" ) @@ -69,11 +70,12 @@ func newPluginClient(sys pluginutil.RunnerUtil, pluginRunner *pluginutil.PluginR // ---- gRPC client domain ---- type gRPCClient struct { - client pb.DatabaseClient + client DatabaseClient + clientConn *grpc.ClientConn } func (c gRPCClient) Type() (string, error) { - resp, err := c.client.Type(context.Background(), &pb.Empty{}) + resp, err := c.client.Type(context.Background(), &Empty{}, grpc.FailFast(true)) if err != nil { return "", err } @@ -82,28 +84,16 @@ func (c gRPCClient) Type() (string, error) { } func (c gRPCClient) CreateUser(ctx context.Context, statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error) { - s := &pb.Statements{ - CreationStatements: statements.CreationStatements, - RevocationStatements: statements.RevocationStatements, - RollbackStatements: statements.RollbackStatements, - RenewStatements: statements.RenewStatements, - } - - u := &pb.UsernameConfig{ - DisplayName: usernameConfig.DisplayName, - RoleName: usernameConfig.RoleName, - } - t, err := ptypes.TimestampProto(expiration) if err != nil { return "", "", err } - resp, err := c.client.CreateUser(ctx, &pb.CreateUserRequest{ - Statements: s, - UsernameConfig: u, + resp, err := c.client.CreateUser(ctx, &CreateUserRequest{ + Statements: &statements, + UsernameConfig: &usernameConfig, Expiration: t, - }) + }, grpc.FailFast(true)) if err != nil { return "", "", err } @@ -112,39 +102,25 @@ func (c gRPCClient) CreateUser(ctx context.Context, statements Statements, usern } func (c *gRPCClient) RenewUser(ctx context.Context, statements Statements, username string, expiration time.Time) error { - s := &pb.Statements{ - CreationStatements: statements.CreationStatements, - RevocationStatements: statements.RevocationStatements, - RollbackStatements: statements.RollbackStatements, - RenewStatements: statements.RenewStatements, - } - t, err := ptypes.TimestampProto(expiration) if err != nil { return err } - _, err = c.client.RenewUser(ctx, &pb.RenewUserRequest{ - Statements: s, + _, err = c.client.RenewUser(ctx, &RenewUserRequest{ + Statements: &statements, Username: username, Expiration: t, - }) + }, grpc.FailFast(true)) return err } func (c *gRPCClient) RevokeUser(ctx context.Context, statements Statements, username string) error { - s := &pb.Statements{ - CreationStatements: statements.CreationStatements, - RevocationStatements: statements.RevocationStatements, - RollbackStatements: statements.RollbackStatements, - RenewStatements: statements.RenewStatements, - } - - _, err := c.client.RevokeUser(ctx, &pb.RevokeUserRequest{ - Statements: s, + _, err := c.client.RevokeUser(ctx, &RevokeUserRequest{ + Statements: &statements, Username: username, - }) + }, grpc.FailFast(true)) return err } @@ -155,15 +131,15 @@ func (c *gRPCClient) Initialize(ctx context.Context, config map[string]interface return err } - _, err = c.client.Initialize(ctx, &pb.InitializeRequest{ + _, err = c.client.Initialize(ctx, &InitializeRequest{ Config: configRaw, VerifyConnection: verifyConnection, - }) + }, grpc.FailFast(true)) return err } func (c *gRPCClient) Close() error { - _, err := c.client.Close(context.Background(), &pb.Empty{}) + _, err := c.client.Close(context.Background(), &Empty{}, grpc.FailFast(true)) return err } diff --git a/builtin/logical/database/dbplugin/pb/database.pb.go b/builtin/logical/database/dbplugin/database.pb.go similarity index 75% rename from builtin/logical/database/dbplugin/pb/database.pb.go rename to builtin/logical/database/dbplugin/database.pb.go index 9c8b9fbad963..c4c4101968a6 100644 --- a/builtin/logical/database/dbplugin/pb/database.pb.go +++ b/builtin/logical/database/dbplugin/database.pb.go @@ -1,11 +1,11 @@ // Code generated by protoc-gen-go. DO NOT EDIT. -// source: builtin/logical/database/dbplugin/pb/database.proto +// source: builtin/logical/database/dbplugin/database.proto /* -Package pb is a generated protocol buffer package. +Package dbplugin is a generated protocol buffer package. It is generated from these files: - builtin/logical/database/dbplugin/pb/database.proto + builtin/logical/database/dbplugin/database.proto It has these top-level messages: InitializeRequest @@ -18,7 +18,7 @@ It has these top-level messages: TypeResponse Empty */ -package pb +package dbplugin import proto "github.com/golang/protobuf/proto" import fmt "fmt" @@ -266,15 +266,15 @@ func (*Empty) ProtoMessage() {} func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } func init() { - proto.RegisterType((*InitializeRequest)(nil), "pb.InitializeRequest") - proto.RegisterType((*CreateUserRequest)(nil), "pb.CreateUserRequest") - proto.RegisterType((*RenewUserRequest)(nil), "pb.RenewUserRequest") - proto.RegisterType((*RevokeUserRequest)(nil), "pb.RevokeUserRequest") - proto.RegisterType((*Statements)(nil), "pb.Statements") - proto.RegisterType((*UsernameConfig)(nil), "pb.UsernameConfig") - proto.RegisterType((*CreateUserResponse)(nil), "pb.CreateUserResponse") - proto.RegisterType((*TypeResponse)(nil), "pb.TypeResponse") - proto.RegisterType((*Empty)(nil), "pb.Empty") + proto.RegisterType((*InitializeRequest)(nil), "dbplugin.InitializeRequest") + proto.RegisterType((*CreateUserRequest)(nil), "dbplugin.CreateUserRequest") + proto.RegisterType((*RenewUserRequest)(nil), "dbplugin.RenewUserRequest") + proto.RegisterType((*RevokeUserRequest)(nil), "dbplugin.RevokeUserRequest") + proto.RegisterType((*Statements)(nil), "dbplugin.Statements") + proto.RegisterType((*UsernameConfig)(nil), "dbplugin.UsernameConfig") + proto.RegisterType((*CreateUserResponse)(nil), "dbplugin.CreateUserResponse") + proto.RegisterType((*TypeResponse)(nil), "dbplugin.TypeResponse") + proto.RegisterType((*Empty)(nil), "dbplugin.Empty") } // Reference imports to suppress errors if they are not otherwise used. @@ -306,7 +306,7 @@ func NewDatabaseClient(cc *grpc.ClientConn) DatabaseClient { func (c *databaseClient) Type(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TypeResponse, error) { out := new(TypeResponse) - err := grpc.Invoke(ctx, "/pb.Database/Type", in, out, c.cc, opts...) + err := grpc.Invoke(ctx, "/dbplugin.Database/Type", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -315,7 +315,7 @@ func (c *databaseClient) Type(ctx context.Context, in *Empty, opts ...grpc.CallO func (c *databaseClient) CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error) { out := new(CreateUserResponse) - err := grpc.Invoke(ctx, "/pb.Database/CreateUser", in, out, c.cc, opts...) + err := grpc.Invoke(ctx, "/dbplugin.Database/CreateUser", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -324,7 +324,7 @@ func (c *databaseClient) CreateUser(ctx context.Context, in *CreateUserRequest, func (c *databaseClient) RenewUser(ctx context.Context, in *RenewUserRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) - err := grpc.Invoke(ctx, "/pb.Database/RenewUser", in, out, c.cc, opts...) + err := grpc.Invoke(ctx, "/dbplugin.Database/RenewUser", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -333,7 +333,7 @@ func (c *databaseClient) RenewUser(ctx context.Context, in *RenewUserRequest, op func (c *databaseClient) RevokeUser(ctx context.Context, in *RevokeUserRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) - err := grpc.Invoke(ctx, "/pb.Database/RevokeUser", in, out, c.cc, opts...) + err := grpc.Invoke(ctx, "/dbplugin.Database/RevokeUser", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -342,7 +342,7 @@ func (c *databaseClient) RevokeUser(ctx context.Context, in *RevokeUserRequest, func (c *databaseClient) Initialize(ctx context.Context, in *InitializeRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) - err := grpc.Invoke(ctx, "/pb.Database/Initialize", in, out, c.cc, opts...) + err := grpc.Invoke(ctx, "/dbplugin.Database/Initialize", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -351,7 +351,7 @@ func (c *databaseClient) Initialize(ctx context.Context, in *InitializeRequest, func (c *databaseClient) Close(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) - err := grpc.Invoke(ctx, "/pb.Database/Close", in, out, c.cc, opts...) + err := grpc.Invoke(ctx, "/dbplugin.Database/Close", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -383,7 +383,7 @@ func _Database_Type_Handler(srv interface{}, ctx context.Context, dec func(inter } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/pb.Database/Type", + FullMethod: "/dbplugin.Database/Type", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DatabaseServer).Type(ctx, req.(*Empty)) @@ -401,7 +401,7 @@ func _Database_CreateUser_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/pb.Database/CreateUser", + FullMethod: "/dbplugin.Database/CreateUser", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DatabaseServer).CreateUser(ctx, req.(*CreateUserRequest)) @@ -419,7 +419,7 @@ func _Database_RenewUser_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/pb.Database/RenewUser", + FullMethod: "/dbplugin.Database/RenewUser", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DatabaseServer).RenewUser(ctx, req.(*RenewUserRequest)) @@ -437,7 +437,7 @@ func _Database_RevokeUser_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/pb.Database/RevokeUser", + FullMethod: "/dbplugin.Database/RevokeUser", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DatabaseServer).RevokeUser(ctx, req.(*RevokeUserRequest)) @@ -455,7 +455,7 @@ func _Database_Initialize_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/pb.Database/Initialize", + FullMethod: "/dbplugin.Database/Initialize", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DatabaseServer).Initialize(ctx, req.(*InitializeRequest)) @@ -473,7 +473,7 @@ func _Database_Close_Handler(srv interface{}, ctx context.Context, dec func(inte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/pb.Database/Close", + FullMethod: "/dbplugin.Database/Close", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DatabaseServer).Close(ctx, req.(*Empty)) @@ -482,7 +482,7 @@ func _Database_Close_Handler(srv interface{}, ctx context.Context, dec func(inte } var _Database_serviceDesc = grpc.ServiceDesc{ - ServiceName: "pb.Database", + ServiceName: "dbplugin.Database", HandlerType: (*DatabaseServer)(nil), Methods: []grpc.MethodDesc{ { @@ -511,47 +511,46 @@ var _Database_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "builtin/logical/database/dbplugin/pb/database.proto", + Metadata: "builtin/logical/database/dbplugin/database.proto", } -func init() { - proto.RegisterFile("builtin/logical/database/dbplugin/pb/database.proto", fileDescriptor0) -} +func init() { proto.RegisterFile("builtin/logical/database/dbplugin/database.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 542 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0x4d, 0x6e, 0xdb, 0x3c, - 0x10, 0x85, 0x1c, 0x27, 0x9f, 0x3d, 0x09, 0x1c, 0x9b, 0x5f, 0x12, 0x04, 0x02, 0x8a, 0x1a, 0xea, - 0x26, 0x45, 0x0b, 0x09, 0x88, 0x77, 0xcd, 0xd2, 0xe9, 0xa2, 0x40, 0xe1, 0x85, 0x9a, 0x00, 0xdd, - 0x19, 0x94, 0x3c, 0x36, 0x88, 0xd0, 0x24, 0x2b, 0x52, 0x4e, 0xdd, 0x9b, 0xb4, 0x67, 0xe9, 0x19, - 0x7a, 0xa6, 0x82, 0x94, 0xf5, 0x67, 0x2f, 0x83, 0xee, 0x38, 0x33, 0xef, 0xcd, 0x3c, 0xcd, 0x8f, - 0x60, 0x92, 0xe4, 0x8c, 0x1b, 0x26, 0x22, 0x2e, 0x57, 0x2c, 0xa5, 0x3c, 0x5a, 0x50, 0x43, 0x13, - 0xaa, 0x31, 0x5a, 0x24, 0x8a, 0xe7, 0x2b, 0x26, 0x22, 0x95, 0x54, 0xce, 0x50, 0x65, 0xd2, 0x48, - 0xd2, 0x51, 0x89, 0xff, 0x7a, 0x25, 0xe5, 0x8a, 0x63, 0xe4, 0x3c, 0x49, 0xbe, 0x8c, 0x0c, 0x5b, - 0xa3, 0x36, 0x74, 0xad, 0x0a, 0x50, 0xf0, 0x15, 0x46, 0x9f, 0x04, 0x33, 0x8c, 0x72, 0xf6, 0x03, - 0x63, 0xfc, 0x96, 0xa3, 0x36, 0xe4, 0x0a, 0x4e, 0x52, 0x29, 0x96, 0x6c, 0x75, 0xed, 0x8d, 0xbd, - 0x9b, 0xb3, 0x78, 0x67, 0x91, 0x77, 0x30, 0xda, 0x60, 0xc6, 0x96, 0xdb, 0x79, 0x2a, 0x85, 0xc0, - 0xd4, 0x30, 0x29, 0xae, 0x3b, 0x63, 0xef, 0xa6, 0x17, 0x0f, 0x8b, 0xc0, 0xb4, 0xf2, 0x07, 0xbf, - 0x3d, 0x18, 0x4d, 0x33, 0xa4, 0x06, 0x1f, 0x35, 0x66, 0x65, 0xea, 0x10, 0x40, 0x1b, 0x6a, 0x70, - 0x8d, 0xc2, 0x68, 0x97, 0xfe, 0xf4, 0x76, 0x10, 0xaa, 0x24, 0xfc, 0x52, 0x79, 0xe3, 0x06, 0x82, - 0xdc, 0xc1, 0x79, 0xae, 0x31, 0x13, 0x74, 0x8d, 0xf3, 0x9d, 0xa6, 0x8e, 0x23, 0x11, 0x4b, 0x7a, - 0xdc, 0x85, 0xa6, 0x2e, 0x12, 0x0f, 0xf2, 0x96, 0x4d, 0x3e, 0x00, 0xe0, 0x77, 0xc5, 0x32, 0xea, - 0x84, 0x1e, 0x39, 0x9e, 0x1f, 0x16, 0x2d, 0x09, 0xcb, 0x96, 0x84, 0x0f, 0x65, 0x4b, 0xe2, 0x06, - 0x3a, 0xf8, 0xe5, 0xc1, 0x30, 0x46, 0x81, 0xcf, 0x2f, 0x51, 0xef, 0x43, 0xaf, 0x94, 0xe4, 0x64, - 0xf7, 0xe3, 0xca, 0x7e, 0x91, 0xb8, 0x39, 0x8c, 0x62, 0xdc, 0xc8, 0x27, 0xfc, 0x47, 0xe2, 0x82, - 0x3f, 0x1e, 0x40, 0x4d, 0x23, 0x11, 0xfc, 0x9f, 0xda, 0x51, 0x32, 0x29, 0xe6, 0x7b, 0x35, 0xfa, - 0x31, 0x29, 0x43, 0x0d, 0xc2, 0x04, 0x2e, 0x33, 0xdc, 0xc8, 0xf4, 0x80, 0x52, 0x14, 0xba, 0xa8, - 0x83, 0xed, 0x2a, 0x99, 0xe4, 0x3c, 0xa1, 0xe9, 0x53, 0x93, 0x72, 0x54, 0x54, 0x29, 0x43, 0x0d, - 0xc2, 0x5b, 0x18, 0x66, 0x76, 0x44, 0x4d, 0x74, 0xd7, 0xa1, 0xcf, 0x9d, 0xbf, 0x86, 0x06, 0x33, - 0x18, 0xb4, 0x97, 0x85, 0x8c, 0xe1, 0xf4, 0x9e, 0x69, 0xc5, 0xe9, 0x76, 0x66, 0x3b, 0x50, 0x7c, - 0x4b, 0xd3, 0x65, 0x1b, 0x14, 0x4b, 0x8e, 0xb3, 0x46, 0x83, 0x4a, 0x3b, 0xf8, 0x0c, 0xa4, 0xb9, - 0xdc, 0x5a, 0x49, 0xa1, 0xb1, 0xd5, 0x52, 0x6f, 0x6f, 0xde, 0x3e, 0xf4, 0x14, 0xd5, 0xfa, 0x59, - 0x66, 0x8b, 0x32, 0x5b, 0x69, 0x07, 0x01, 0x9c, 0x3d, 0x6c, 0x15, 0x56, 0x79, 0x08, 0x74, 0xcd, - 0x56, 0x95, 0x39, 0xdc, 0x3b, 0xf8, 0x0f, 0x8e, 0x3f, 0xae, 0x95, 0xd9, 0xde, 0xfe, 0xec, 0x40, - 0xef, 0x7e, 0x77, 0xea, 0xe4, 0x0d, 0x74, 0x2d, 0x93, 0xf4, 0xed, 0xa0, 0x5d, 0xdc, 0x1f, 0xda, - 0x67, 0x2b, 0xdd, 0x1d, 0x40, 0x2d, 0x96, 0x5c, 0xda, 0xf8, 0xc1, 0x65, 0xfa, 0x57, 0xfb, 0xee, - 0x1d, 0xf9, 0x3d, 0xf4, 0xab, 0x3b, 0x20, 0x17, 0x16, 0xb4, 0x7f, 0x16, 0x7e, 0x5d, 0xdc, 0x2e, - 0x61, 0xbd, 0x99, 0x45, 0xa9, 0x83, 0x4d, 0xdd, 0xc3, 0xd7, 0xff, 0x9f, 0x02, 0x7f, 0xf0, 0x3f, - 0x6a, 0xe2, 0x5f, 0xc1, 0xf1, 0x94, 0x4b, 0xdd, 0xfa, 0xe0, 0xfa, 0x99, 0x9c, 0xb8, 0xc3, 0x99, - 0xfc, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xe6, 0xbc, 0xdd, 0x88, 0x31, 0x05, 0x00, 0x00, + // 548 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xcf, 0x6e, 0xd3, 0x4e, + 0x10, 0x96, 0xdb, 0xb4, 0xbf, 0x64, 0x5a, 0x35, 0xc9, 0xfe, 0x4a, 0x15, 0x19, 0x24, 0x22, 0x9f, + 0x5a, 0x21, 0xd9, 0xa8, 0xe5, 0x80, 0xb8, 0xa1, 0x14, 0x21, 0x24, 0x94, 0x83, 0x69, 0x25, 0x6e, + 0xd1, 0xda, 0x99, 0x44, 0xab, 0x3a, 0xbb, 0xc6, 0xbb, 0x4e, 0x09, 0x4f, 0xc3, 0xe3, 0x70, 0xe2, + 0x1d, 0x78, 0x13, 0xe4, 0x75, 0xd6, 0xbb, 0xf9, 0x73, 0xab, 0xb8, 0x79, 0x66, 0xbe, 0x6f, 0xf6, + 0xf3, 0xb7, 0x33, 0x0b, 0xaf, 0x93, 0x92, 0x65, 0x8a, 0xf1, 0x28, 0x13, 0x73, 0x96, 0xd2, 0x2c, + 0x9a, 0x52, 0x45, 0x13, 0x2a, 0x31, 0x9a, 0x26, 0x79, 0x56, 0xce, 0x19, 0x6f, 0x32, 0x61, 0x5e, + 0x08, 0x25, 0x48, 0xdb, 0x14, 0xfc, 0x97, 0x73, 0x21, 0xe6, 0x19, 0x46, 0x3a, 0x9f, 0x94, 0xb3, + 0x48, 0xb1, 0x05, 0x4a, 0x45, 0x17, 0x79, 0x0d, 0x0d, 0xbe, 0x42, 0xff, 0x13, 0x67, 0x8a, 0xd1, + 0x8c, 0xfd, 0xc0, 0x18, 0xbf, 0x95, 0x28, 0x15, 0xb9, 0x80, 0xe3, 0x54, 0xf0, 0x19, 0x9b, 0x0f, + 0xbc, 0xa1, 0x77, 0x79, 0x1a, 0xaf, 0x23, 0xf2, 0x0a, 0xfa, 0x4b, 0x2c, 0xd8, 0x6c, 0x35, 0x49, + 0x05, 0xe7, 0x98, 0x2a, 0x26, 0xf8, 0xe0, 0x60, 0xe8, 0x5d, 0xb6, 0xe3, 0x5e, 0x5d, 0x18, 0x35, + 0xf9, 0xe0, 0x97, 0x07, 0xfd, 0x51, 0x81, 0x54, 0xe1, 0xbd, 0xc4, 0xc2, 0xb4, 0x7e, 0x03, 0x20, + 0x15, 0x55, 0xb8, 0x40, 0xae, 0xa4, 0x6e, 0x7f, 0x72, 0x7d, 0x1e, 0x1a, 0xbd, 0xe1, 0x97, 0xa6, + 0x16, 0x3b, 0x38, 0xf2, 0x1e, 0xba, 0xa5, 0xc4, 0x82, 0xd3, 0x05, 0x4e, 0xd6, 0xca, 0x0e, 0x34, + 0x75, 0x60, 0xa9, 0xf7, 0x6b, 0xc0, 0x48, 0xd7, 0xe3, 0xb3, 0x72, 0x23, 0x26, 0xef, 0x00, 0xf0, + 0x7b, 0xce, 0x0a, 0xaa, 0x45, 0x1f, 0x6a, 0xb6, 0x1f, 0xd6, 0xf6, 0x84, 0xc6, 0x9e, 0xf0, 0xce, + 0xd8, 0x13, 0x3b, 0xe8, 0xe0, 0xa7, 0x07, 0xbd, 0x18, 0x39, 0x3e, 0x3e, 0xfd, 0x4f, 0x7c, 0x68, + 0x1b, 0x61, 0xfa, 0x17, 0x3a, 0x71, 0x13, 0x3f, 0x49, 0x22, 0x42, 0x3f, 0xc6, 0xa5, 0x78, 0xc0, + 0x7f, 0x2a, 0x31, 0xf8, 0xed, 0x01, 0x58, 0x1a, 0x89, 0xe0, 0xff, 0xb4, 0xba, 0x62, 0x26, 0xf8, + 0x64, 0xeb, 0xa4, 0x4e, 0x4c, 0x4c, 0xc9, 0x21, 0xdc, 0xc0, 0xb3, 0x02, 0x97, 0x22, 0xdd, 0xa1, + 0xd4, 0x07, 0x9d, 0xdb, 0xe2, 0xe6, 0x29, 0x85, 0xc8, 0xb2, 0x84, 0xa6, 0x0f, 0x2e, 0xe5, 0xb0, + 0x3e, 0xc5, 0x94, 0x1c, 0xc2, 0x15, 0xf4, 0x8a, 0xea, 0xba, 0x5c, 0x74, 0x4b, 0xa3, 0xbb, 0x3a, + 0x6f, 0xa1, 0xc1, 0x18, 0xce, 0x36, 0x07, 0x87, 0x0c, 0xe1, 0xe4, 0x96, 0xc9, 0x3c, 0xa3, 0xab, + 0x71, 0xe5, 0x40, 0xfd, 0x2f, 0x6e, 0xaa, 0x32, 0x28, 0x16, 0x19, 0x8e, 0x1d, 0x83, 0x4c, 0x1c, + 0x7c, 0x06, 0xe2, 0x0e, 0xbd, 0xcc, 0x05, 0x97, 0xb8, 0x61, 0xa9, 0xb7, 0x75, 0xeb, 0x3e, 0xb4, + 0x73, 0x2a, 0xe5, 0xa3, 0x28, 0xa6, 0xa6, 0x9b, 0x89, 0x83, 0x00, 0x4e, 0xef, 0x56, 0x39, 0x36, + 0x7d, 0x08, 0xb4, 0xd4, 0x2a, 0x37, 0x3d, 0xf4, 0x77, 0xf0, 0x1f, 0x1c, 0x7d, 0x58, 0xe4, 0x6a, + 0x75, 0xfd, 0xe7, 0x00, 0xda, 0xb7, 0xeb, 0x87, 0x80, 0x44, 0xd0, 0xaa, 0x98, 0xa4, 0x6b, 0xaf, + 0x5b, 0xa3, 0xfc, 0x0b, 0x9b, 0xd8, 0x68, 0xfd, 0x11, 0xc0, 0x0a, 0x27, 0xcf, 0x2d, 0x6a, 0x67, + 0x87, 0xfd, 0x17, 0xfb, 0x8b, 0xeb, 0x46, 0x6f, 0xa1, 0xd3, 0xec, 0x0a, 0xf1, 0x2d, 0x74, 0x7b, + 0x81, 0xfc, 0x6d, 0x69, 0xd5, 0xfc, 0xdb, 0x19, 0x76, 0x25, 0xec, 0x4c, 0xf6, 0x5e, 0xae, 0x7d, + 0xc7, 0x5c, 0xee, 0xce, 0xeb, 0xb6, 0xcb, 0xbd, 0x82, 0xa3, 0x51, 0x26, 0xe4, 0x1e, 0xb3, 0xb6, + 0x13, 0xc9, 0xb1, 0x5e, 0xc3, 0x9b, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8c, 0x55, 0x84, 0x56, + 0x94, 0x05, 0x00, 0x00, } diff --git a/builtin/logical/database/dbplugin/pb/database.proto b/builtin/logical/database/dbplugin/database.proto similarity index 98% rename from builtin/logical/database/dbplugin/pb/database.proto rename to builtin/logical/database/dbplugin/database.proto index 75fb28619aa5..d5e7d4068f7d 100644 --- a/builtin/logical/database/dbplugin/pb/database.proto +++ b/builtin/logical/database/dbplugin/database.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -package pb; +package dbplugin; import "google/protobuf/timestamp.proto"; diff --git a/builtin/logical/database/dbplugin/plugin.go b/builtin/logical/database/dbplugin/plugin.go index 9c7f55e4e45f..53590f408289 100644 --- a/builtin/logical/database/dbplugin/plugin.go +++ b/builtin/logical/database/dbplugin/plugin.go @@ -8,7 +8,6 @@ import ( "google.golang.org/grpc" "github.com/hashicorp/go-plugin" - "github.com/hashicorp/vault/builtin/logical/database/dbplugin/pb" "github.com/hashicorp/vault/helper/pluginutil" log "github.com/mgutz/logxi/v1" ) @@ -24,21 +23,6 @@ type Database interface { Close() error } -// Statements set in role creation and passed into the database type's functions. -type Statements struct { - CreationStatements string `json:"creation_statments" mapstructure:"creation_statements" structs:"creation_statments"` - RevocationStatements string `json:"revocation_statements" mapstructure:"revocation_statements" structs:"revocation_statements"` - RollbackStatements string `json:"rollback_statements" mapstructure:"rollback_statements" structs:"rollback_statements"` - RenewStatements string `json:"renew_statements" mapstructure:"renew_statements" structs:"renew_statements"` -} - -// UsernameConfig is used to configure prefixes for the username to be -// generated. -type UsernameConfig struct { - DisplayName string - RoleName string -} - // PluginFactory is used to build plugin database types. It wraps the database // object in a logging and metrics middleware. func PluginFactory(pluginName string, sys pluginutil.LookRunnerUtil, logger log.Logger) (Database, error) { @@ -112,10 +96,13 @@ type DatabasePlugin struct { } func (d DatabasePlugin) GRPCServer(s *grpc.Server) error { - pb.RegisterDatabaseServer(s, &gRPCServer{impl: d.impl}) + RegisterDatabaseServer(s, &gRPCServer{impl: d.impl}) return nil } func (DatabasePlugin) GRPCClient(c *grpc.ClientConn) (interface{}, error) { - return &gRPCClient{client: pb.NewDatabaseClient(c)}, nil + return &gRPCClient{ + client: NewDatabaseClient(c), + clientConn: c, + }, nil } diff --git a/builtin/logical/database/dbplugin/server.go b/builtin/logical/database/dbplugin/server.go index 160310fbd044..471b9a3866fb 100644 --- a/builtin/logical/database/dbplugin/server.go +++ b/builtin/logical/database/dbplugin/server.go @@ -7,7 +7,6 @@ import ( "github.com/golang/protobuf/ptypes" "github.com/hashicorp/go-plugin" - "github.com/hashicorp/vault/builtin/logical/database/dbplugin/pb" ) // Serve is called from within a plugin and wraps the provided @@ -37,72 +36,46 @@ type gRPCServer struct { impl Database } -func (s *gRPCServer) Type(context.Context, *pb.Empty) (*pb.TypeResponse, error) { +func (s *gRPCServer) Type(context.Context, *Empty) (*TypeResponse, error) { t, err := s.impl.Type() if err != nil { return nil, err } - return &pb.TypeResponse{ + return &TypeResponse{ Type: t, }, nil } -func (s *gRPCServer) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) { - statements := Statements{ - CreationStatements: req.Statements.CreationStatements, - RevocationStatements: req.Statements.RevocationStatements, - RollbackStatements: req.Statements.RollbackStatements, - RenewStatements: req.Statements.RenewStatements, - } - - usernameConfig := UsernameConfig{ - DisplayName: req.UsernameConfig.DisplayName, - RoleName: req.UsernameConfig.RoleName, - } - +func (s *gRPCServer) CreateUser(ctx context.Context, req *CreateUserRequest) (*CreateUserResponse, error) { e, err := ptypes.Timestamp(req.Expiration) if err != nil { return nil, err } - u, p, err := s.impl.CreateUser(ctx, statements, usernameConfig, e) + u, p, err := s.impl.CreateUser(ctx, *req.Statements, *req.UsernameConfig, e) - return &pb.CreateUserResponse{ + return &CreateUserResponse{ Username: u, Password: p, }, err } -func (s *gRPCServer) RenewUser(ctx context.Context, req *pb.RenewUserRequest) (*pb.Empty, error) { - statements := Statements{ - CreationStatements: req.Statements.CreationStatements, - RevocationStatements: req.Statements.RevocationStatements, - RollbackStatements: req.Statements.RollbackStatements, - RenewStatements: req.Statements.RenewStatements, - } - +func (s *gRPCServer) RenewUser(ctx context.Context, req *RenewUserRequest) (*Empty, error) { e, err := ptypes.Timestamp(req.Expiration) if err != nil { return nil, err } - err = s.impl.RenewUser(ctx, statements, req.Username, e) - return &pb.Empty{}, err + err = s.impl.RenewUser(ctx, *req.Statements, req.Username, e) + return &Empty{}, err } -func (s *gRPCServer) RevokeUser(ctx context.Context, req *pb.RevokeUserRequest) (*pb.Empty, error) { - statements := Statements{ - CreationStatements: req.Statements.CreationStatements, - RevocationStatements: req.Statements.RevocationStatements, - RollbackStatements: req.Statements.RollbackStatements, - RenewStatements: req.Statements.RenewStatements, - } - - err := s.impl.RevokeUser(ctx, statements, req.Username) - return &pb.Empty{}, err +func (s *gRPCServer) RevokeUser(ctx context.Context, req *RevokeUserRequest) (*Empty, error) { + err := s.impl.RevokeUser(ctx, *req.Statements, req.Username) + return &Empty{}, err } -func (s *gRPCServer) Initialize(ctx context.Context, req *pb.InitializeRequest) (*pb.Empty, error) { +func (s *gRPCServer) Initialize(ctx context.Context, req *InitializeRequest) (*Empty, error) { config := map[string]interface{}{} err := json.Unmarshal(req.Config, &config) @@ -111,10 +84,10 @@ func (s *gRPCServer) Initialize(ctx context.Context, req *pb.InitializeRequest) } err = s.impl.Initialize(ctx, config, req.VerifyConnection) - return &pb.Empty{}, err + return &Empty{}, err } -func (s *gRPCServer) Close(_ context.Context, _ *pb.Empty) (*pb.Empty, error) { +func (s *gRPCServer) Close(_ context.Context, _ *Empty) (*Empty, error) { s.impl.Close() - return &pb.Empty{}, nil + return &Empty{}, nil } From 7a15dd262aa2f9d26ac6620490f63e1425f40a3f Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Mon, 4 Dec 2017 17:21:04 -0800 Subject: [PATCH 7/9] Add a grpc mechanism for running backend plugins --- logical/plugin/backend_client.go | 44 +- logical/plugin/backend_server.go | 18 +- logical/plugin/context.go | 119 -- logical/plugin/grpc_backend_client.go | 214 +++ logical/plugin/grpc_backend_server.go | 141 ++ logical/plugin/grpc_storage.go | 110 ++ logical/plugin/grpc_system.go | 193 +++ logical/plugin/pb/backend.pb.go | 2177 +++++++++++++++++++++++++ logical/plugin/pb/backend.proto | 406 +++++ logical/plugin/pb/translation.go | 323 ++++ 10 files changed, 3568 insertions(+), 177 deletions(-) delete mode 100644 logical/plugin/context.go create mode 100644 logical/plugin/grpc_backend_client.go create mode 100644 logical/plugin/grpc_backend_server.go create mode 100644 logical/plugin/grpc_storage.go create mode 100644 logical/plugin/grpc_system.go create mode 100644 logical/plugin/pb/backend.pb.go create mode 100644 logical/plugin/pb/backend.proto create mode 100644 logical/plugin/pb/translation.go diff --git a/logical/plugin/backend_client.go b/logical/plugin/backend_client.go index 5864a9c3e108..53c1ad72ed44 100644 --- a/logical/plugin/backend_client.go +++ b/logical/plugin/backend_client.go @@ -43,12 +43,6 @@ type SpecialPathsReply struct { Paths *logical.Paths } -// SystemReply is the reply for System method. -type SystemReply struct { - SystemView logical.SystemView - Error error -} - // HandleExistenceCheckArgs is the args for HandleExistenceCheck method. type HandleExistenceCheckArgs struct { StorageID uint32 @@ -99,19 +93,8 @@ func (b *backendPluginClient) HandleRequest(req *logical.Request) (*logical.Resp // interfaces. The server will pick up the storage from the shim. req.Storage = nil - contextID := b.broker.NextId() - go b.broker.AcceptAndServe(contextID, &ContextServer{ - ctx: req.Context, - }) - - ctx := req.Context - req.Context = nil - cancelID := b.broker.NextId() - args := &HandleRequestArgs{ - Request: req, - ContextID: contextID, - ContextCancelID: cancelID, + Request: req, } var reply HandleRequestReply @@ -123,30 +106,7 @@ func (b *backendPluginClient) HandleRequest(req *logical.Request) (*logical.Resp }() } - c := make(chan error) - quit := make(chan struct{}) - go func() { - c <- b.client.Call("Plugin.HandleRequest", args, &reply) - }() - - ctxConn, err := b.broker.Dial(cancelID) - if err != nil { - return nil, err - } - defer ctxConn.Close() - ctxClient := rpc.NewClient(ctxConn) - - canceler := &ContextCancelClient{client: ctxClient} - go func() { - select { - case <-ctx.Done(): - canceler.Cancel() - case <-quit: - } - }() - - err = <-c - close(quit) + err := b.client.Call("Plugin.HandleRequest", args, &reply) if err != nil { return nil, err } diff --git a/logical/plugin/backend_server.go b/logical/plugin/backend_server.go index cb6431358bc5..b03edc7a706b 100644 --- a/logical/plugin/backend_server.go +++ b/logical/plugin/backend_server.go @@ -1,6 +1,7 @@ package plugin import ( + "context" "errors" "net/rpc" "os" @@ -35,22 +36,7 @@ func (b *backendPluginServer) HandleRequest(args *HandleRequestArgs, reply *Hand return ErrServerInMetadataMode } - ctxConn, err := b.broker.Dial(args.ContextID) - if err != nil { - *reply = HandleRequestReply{ - Error: wrapError(err), - } - return nil - } - ctxClient := rpc.NewClient(ctxConn) - - ctx := &ContextClient{client: ctxClient} - - go b.broker.AcceptAndServe(args.ContextCancelID, &ContextCancelServer{ - ctx.CancelFunc(), - }) - - args.Request.Context = ctx + args.Request.Context = context.Background() storage := &StorageClient{client: b.storageClient} args.Request.Storage = storage diff --git a/logical/plugin/context.go b/logical/plugin/context.go deleted file mode 100644 index 5c670c1ec597..000000000000 --- a/logical/plugin/context.go +++ /dev/null @@ -1,119 +0,0 @@ -package plugin - -import ( - "context" - "net/rpc" - "time" -) - -type ContextCancelClient struct { - client *rpc.Client -} - -func (c *ContextCancelClient) Cancel() { - c.client.Call("Plugin.ContextCancel", struct{}{}, struct{}{}) -} - -type ContextCancelServer struct { - f context.CancelFunc -} - -func (c ContextCancelServer) ContextCancel(_ struct{}, _ struct{}) { - c.f() -} - -// StorageClient is an implementation of logical.Storage that communicates -// over RPC. -type ContextClient struct { - client *rpc.Client - d chan struct{} - cachedErr error -} - -func (c *ContextClient) CancelFunc() context.CancelFunc { - return func() { close(c.d) } -} - -func (c *ContextClient) Deadline() (deadline time.Time, ok bool) { - var reply ContextDeadlineReply - err := c.client.Call("Plugin.Deadline", struct{}{}, &reply) - if err != nil { - return time.Time{}, false - } - - return reply.Deadline, reply.Ok -} -func (c *ContextClient) Done() <-chan struct{} { - return c.d -} - -func (c *ContextClient) Err() error { - if c.cachedErr != nil { - return c.cachedErr - } - - var reply ContextErrReply - err := c.client.Call("Plugin.Err", struct{}{}, &reply) - if err != nil { - return err - } - - if reply.Err != nil { - c.cachedErr = reply.Err - } - - return reply.Err -} - -func (c *ContextClient) Value(key interface{}) interface{} { - var reply ContextValueReply - err := c.client.Call("Plugin.Value", key, &reply) - if err != nil { - return nil - } - - return reply.Value -} - -// StorageServer is a net/rpc compatible structure for serving -type ContextServer struct { - ctx context.Context -} - -func (c *ContextServer) Deadline(_ struct{}, reply *ContextDeadlineReply) error { - d, ok := c.ctx.Deadline() - *reply = ContextDeadlineReply{ - Deadline: d, - Ok: ok, - } - return nil -} - -func (c *ContextServer) Err(_ struct{}, reply *ContextErrReply) error { - err := c.ctx.Err() - *reply = ContextErrReply{ - Err: err, - } - return nil -} - -func (c *ContextServer) Value(key interface{}, reply *ContextValueReply) error { - v := c.ctx.Value(key) - *reply = ContextValueReply{ - Value: v, - } - return nil -} - -type ContextErrReply struct { - Err error -} - -type ContextDeadlineReply struct { - Deadline time.Time - Ok bool -} - -type ContextValueReply struct { - Value interface{} -} diff --git a/logical/plugin/grpc_backend_client.go b/logical/plugin/grpc_backend_client.go new file mode 100644 index 000000000000..0d3891769a1a --- /dev/null +++ b/logical/plugin/grpc_backend_client.go @@ -0,0 +1,214 @@ +package plugin + +import ( + "context" + "errors" + + "google.golang.org/grpc" + + "github.com/hashicorp/go-plugin" + "github.com/hashicorp/vault/logical" + "github.com/hashicorp/vault/logical/plugin/pb" + log "github.com/mgutz/logxi/v1" +) + +// backendPluginClient implements logical.Backend and is the +// go-plugin client. +type backendGRPCPluginClient struct { + broker *plugin.GRPCBroker + client pb.BackendClient + metadataMode bool + + system logical.SystemView + logger log.Logger + + server *grpc.Server +} + +func (b *backendGRPCPluginClient) HandleRequest(req *logical.Request) (*logical.Response, error) { + if b.metadataMode { + return nil, ErrClientInMetadataMode + } + + protoReq, err := pb.LogicalRequestToProtoRequest(req) + if err != nil { + return nil, err + } + + reply, err := b.client.HandleRequest(req.Context, &pb.HandleRequestArgs{ + Request: protoReq, + }) + if err != nil { + return nil, err + } + resp, err := pb.ProtoResponseToLogicalResponse(reply.Response) + if err != nil { + return nil, err + } + if reply.Err != "" { + if reply.Err == logical.ErrUnsupportedOperation.Error() { + return nil, logical.ErrUnsupportedOperation + } + + return resp, errors.New(reply.Err) + } + + return resp, nil +} + +func (b *backendGRPCPluginClient) SpecialPaths() *logical.Paths { + reply, err := b.client.SpecialPaths(context.Background(), &pb.Empty{}) + if err != nil { + return nil + } + + return &logical.Paths{ + Root: reply.Paths.Root, + Unauthenticated: reply.Paths.Unauthenticated, + LocalStorage: reply.Paths.LocalStorage, + SealWrapStorage: reply.Paths.SealWrapStorage, + } +} + +// System returns vault's system view. The backend client stores the view during +// Setup, so there is no need to shim the system just to get it back. +func (b *backendGRPCPluginClient) System() logical.SystemView { + return b.system +} + +// Logger returns vault's logger. The backend client stores the logger during +// Setup, so there is no need to shim the logger just to get it back. +func (b *backendGRPCPluginClient) Logger() log.Logger { + return b.logger +} + +func (b *backendGRPCPluginClient) HandleExistenceCheck(req *logical.Request) (bool, bool, error) { + if b.metadataMode { + return false, false, ErrClientInMetadataMode + } + + protoReq, err := pb.LogicalRequestToProtoRequest(req) + if err != nil { + return false, false, err + } + + reply, err := b.client.HandleExistenceCheck(req.Context, &pb.HandleExistenceCheckArgs{ + Request: protoReq, + }) + if err != nil { + return false, false, err + } + if reply.Err != "" { + // THINKING: Should be be a switch on all error types? + if reply.Err == logical.ErrUnsupportedPath.Error() { + return false, false, logical.ErrUnsupportedPath + } + return false, false, errors.New(reply.Err) + } + + return reply.CheckFound, reply.Exists, nil +} + +func (b *backendGRPCPluginClient) Cleanup() { + b.client.Cleanup(context.Background(), &pb.Empty{}) +} + +func (b *backendGRPCPluginClient) Initialize() error { + if b.metadataMode { + return ErrClientInMetadataMode + } + _, err := b.client.Initialize(context.Background(), &pb.Empty{}) + return err +} + +func (b *backendGRPCPluginClient) InvalidateKey(key string) { + if b.metadataMode { + return + } + b.client.InvalidateKey(context.Background(), &pb.InvalidateKeyArgs{ + Key: key, + }) +} + +func (b *backendGRPCPluginClient) Setup(config *logical.BackendConfig) error { + // Shim logical.Storage + storageImpl := config.StorageView + if b.metadataMode { + storageImpl = &NOOPStorage{} + } + storage := &GRPCStorageServer{ + impl: storageImpl, + } + + // Shim log.Logger + /* loggerImpl := config.Logger + if b.metadataMode { + loggerImpl = log.NullLog + } + */ + // Shim logical.SystemView + sysViewImpl := config.System + if b.metadataMode { + sysViewImpl = &logical.StaticSystemView{} + } + sysView := &gRPCSystemViewServer{ + impl: sysViewImpl, + } + + serverFunc := func(opts []grpc.ServerOption) *grpc.Server { + s := grpc.NewServer(opts...) + pb.RegisterSystemViewServer(s, sysView) + pb.RegisterStorageServer(s, storage) + b.server = s + return s + } + brokerID := b.broker.NextId() + go b.broker.AcceptAndServe(brokerID, serverFunc) + + args := &pb.SetupArgs{ + BrokerId: brokerID, + Config: config.Config, + } + + reply, err := b.client.Setup(context.Background(), args) + if err != nil { + return err + } + if reply.Err != "" { + return errors.New(reply.Err) + } + + // Set system and logger for getter methods + b.system = config.System + b.logger = config.Logger + + return nil +} + +func (b *backendGRPCPluginClient) Type() logical.BackendType { + reply, err := b.client.Type(context.Background(), &pb.Empty{}) + if err != nil { + return logical.TypeUnknown + } + + return logical.BackendType(reply.Type) +} + +func (b *backendGRPCPluginClient) RegisterLicense(license interface{}) error { + if b.metadataMode { + return ErrClientInMetadataMode + } + + args := &pb.RegisterLicenseArgs{ + // License: license, + } + reply, err := b.client.RegisterLicense(context.Background(), args) + if err != nil { + return err + } + if reply.Err != "" { + return errors.New(reply.Err) + } + + return nil +} diff --git a/logical/plugin/grpc_backend_server.go b/logical/plugin/grpc_backend_server.go new file mode 100644 index 000000000000..2c37ab14fcd9 --- /dev/null +++ b/logical/plugin/grpc_backend_server.go @@ -0,0 +1,141 @@ +package plugin + +import ( + "context" + + plugin "github.com/hashicorp/go-plugin" + "github.com/hashicorp/vault/logical" + "github.com/hashicorp/vault/logical/plugin/pb" + "google.golang.org/grpc" +) + +type backendGRPCPluginServer struct { + broker *plugin.GRPCBroker + backend logical.Backend + + factory func(*logical.BackendConfig) (logical.Backend, error) + + brokeredClient *grpc.ClientConn +} + +// Setup dials into the plugin's broker to get a shimmed storage, logger, and +// system view of the backend. This method also instantiates the underlying +// backend through its factory func for the server side of the plugin. +func (b *backendGRPCPluginServer) Setup(ctx context.Context, args *pb.SetupArgs) (*pb.SetupReply, error) { + // Dial for storage + brokeredClient, err := b.broker.Dial(args.BrokerId) + if err != nil { + return nil, err + } + b.brokeredClient = brokeredClient + storage := newGRPCStorageClient(brokeredClient) + sysView := newGRPCSystemView(brokeredClient) + + config := &logical.BackendConfig{ + StorageView: storage, + // Logger: logger, + System: sysView, + Config: args.Config, + } + + // Call the underlying backend factory after shims have been created + // to set b.backend + backend, err := b.factory(config) + if err != nil { + return nil, err + } + b.backend = backend + + return &pb.SetupReply{}, nil +} + +func (b *backendGRPCPluginServer) HandleRequest(ctx context.Context, args *pb.HandleRequestArgs) (*pb.HandleRequestReply, error) { + if inMetadataMode() { + return nil, ErrServerInMetadataMode + } + + logicalReq, err := pb.ProtoRequestToLogicalRequest(args.Request) + if err != nil { + return nil, err + } + + // logicalReq.Storage = &StorageClient{client: b.storageClient} + + resp, err := b.backend.HandleRequest(logicalReq) + if err != nil { + return nil, err + } + + pbResp, err := pb.LogicalResponseToProtoResp(resp) + if err != nil { + return nil, err + } + + return &pb.HandleRequestReply{ + Response: pbResp, + }, nil +} + +func (b *backendGRPCPluginServer) SpecialPaths(ctx context.Context, args *pb.Empty) (*pb.SpecialPathsReply, error) { + paths := b.backend.SpecialPaths() + + return &pb.SpecialPathsReply{ + Paths: &pb.Paths{ + Root: paths.Root, + Unauthenticated: paths.Unauthenticated, + LocalStorage: paths.LocalStorage, + SealWrapStorage: paths.SealWrapStorage, + }, + }, nil +} + +func (b *backendGRPCPluginServer) HandleExistenceCheck(ctx context.Context, args *pb.HandleExistenceCheckArgs) (*pb.HandleExistenceCheckReply, error) { + if inMetadataMode() { + return nil, ErrServerInMetadataMode + } + + logicalReq, err := pb.ProtoRequestToLogicalRequest(args.Request) + if err != nil { + return nil, err + } + // storage := &StorageClient{client: b.storageClient} + // logicalReq.Storage = storage + checkFound, exists, err := b.backend.HandleExistenceCheck(logicalReq) + return &pb.HandleExistenceCheckReply{ + CheckFound: checkFound, + Exists: exists, + Err: err.Error(), + }, nil +} + +func (b *backendGRPCPluginServer) Cleanup(ctx context.Context, _ *pb.Empty) (*pb.Empty, error) { + b.backend.Cleanup() + + // Close rpc clients + b.brokeredClient.Close() + return nil, nil +} + +func (b *backendGRPCPluginServer) Initialize(ctx context.Context, _ *pb.Empty) (*pb.Empty, error) { + if inMetadataMode() { + return nil, ErrServerInMetadataMode + } + + err := b.backend.Initialize() + return nil, err +} + +func (b *backendGRPCPluginServer) Type(ctx context.Context, _ *pb.Empty) (*pb.TypeReply, error) { + return &pb.TypeReply{ + Type: uint32(b.backend.Type()), + }, nil +} + +func (b *backendGRPCPluginServer) RegisterLicense(ctx context.Context, _ *pb.RegisterLicenseArgs) (*pb.RegisterLicenseReply, error) { + if inMetadataMode() { + return nil, ErrServerInMetadataMode + } + + err := b.backend.RegisterLicense(struct{}{}) + return nil, err +} diff --git a/logical/plugin/grpc_storage.go b/logical/plugin/grpc_storage.go new file mode 100644 index 000000000000..2a3df4a40b95 --- /dev/null +++ b/logical/plugin/grpc_storage.go @@ -0,0 +1,110 @@ +package plugin + +import ( + "context" + "errors" + + "google.golang.org/grpc" + + "github.com/hashicorp/vault/logical" + "github.com/hashicorp/vault/logical/plugin/pb" +) + +func newGRPCStorageClient(conn *grpc.ClientConn) *GRPCStorageClient { + return &GRPCStorageClient{ + client: pb.NewStorageClient(conn), + } +} + +// GRPCStorageClient is an implementation of logical.Storage that communicates +// over RPC. +type GRPCStorageClient struct { + client pb.StorageClient +} + +func (s *GRPCStorageClient) List(prefix string) ([]string, error) { + reply, err := s.client.List(context.Background(), &pb.StorageListArgs{ + Prefix: prefix, + }) + if err != nil { + return reply.Keys, err + } + if reply.Err != "" { + return reply.Keys, errors.New(reply.Err) + } + return reply.Keys, nil +} + +func (s *GRPCStorageClient) Get(key string) (*logical.StorageEntry, error) { + reply, err := s.client.Get(context.Background(), &pb.StorageGetArgs{ + Key: key, + }) + if err != nil { + return nil, err + } + if reply.Err != "" { + return nil, errors.New(reply.Err) + } + return pb.ProtoStorageEntryToLogicalStorageEntry(reply.Entry), nil +} + +func (s *GRPCStorageClient) Put(entry *logical.StorageEntry) error { + reply, err := s.client.Put(context.Background(), &pb.StoragePutArgs{ + Entry: pb.LogicalStorageEntryToProtoStorageEntry(entry), + }) + if err != nil { + return err + } + if reply.Err != "" { + return errors.New(reply.Err) + } + return nil +} + +func (s *GRPCStorageClient) Delete(key string) error { + reply, err := s.client.Delete(context.Background(), &pb.StorageDeleteArgs{ + Key: key, + }) + if err != nil { + return err + } + if reply.Err != "" { + return errors.New(reply.Err) + } + return nil +} + +// StorageServer is a net/rpc compatible structure for serving +type GRPCStorageServer struct { + impl logical.Storage +} + +func (s *GRPCStorageServer) List(ctx context.Context, args *pb.StorageListArgs) (*pb.StorageListReply, error) { + keys, err := s.impl.List(args.Prefix) + return &pb.StorageListReply{ + Keys: keys, + Err: pb.ErrToString(err), + }, nil +} + +func (s *GRPCStorageServer) Get(ctx context.Context, args *pb.StorageGetArgs) (*pb.StorageGetReply, error) { + storageEntry, err := s.impl.Get(args.Key) + return &pb.StorageGetReply{ + Entry: pb.LogicalStorageEntryToProtoStorageEntry(storageEntry), + Err: pb.ErrToString(err), + }, nil +} + +func (s *GRPCStorageServer) Put(ctx context.Context, args *pb.StoragePutArgs) (*pb.StoragePutReply, error) { + err := s.impl.Put(pb.ProtoStorageEntryToLogicalStorageEntry(args.Entry)) + return &pb.StoragePutReply{ + Err: pb.ErrToString(err), + }, nil +} + +func (s *GRPCStorageServer) Delete(ctx context.Context, args *pb.StorageDeleteArgs) (*pb.StorageDeleteReply, error) { + err := s.impl.Delete(args.Key) + return &pb.StorageDeleteReply{ + Err: pb.ErrToString(err), + }, nil +} diff --git a/logical/plugin/grpc_system.go b/logical/plugin/grpc_system.go new file mode 100644 index 000000000000..34b0f3b22d20 --- /dev/null +++ b/logical/plugin/grpc_system.go @@ -0,0 +1,193 @@ +package plugin + +import ( + "context" + "encoding/json" + "errors" + "time" + + "google.golang.org/grpc" + + "fmt" + + "github.com/hashicorp/vault/helper/consts" + "github.com/hashicorp/vault/helper/pluginutil" + "github.com/hashicorp/vault/helper/wrapping" + "github.com/hashicorp/vault/logical" + "github.com/hashicorp/vault/logical/plugin/pb" +) + +func newGRPCSystemView(conn *grpc.ClientConn) *gRPCSystemViewClient { + return &gRPCSystemViewClient{ + client: pb.NewSystemViewClient(conn), + } +} + +type gRPCSystemViewClient struct { + client pb.SystemViewClient +} + +func (s *gRPCSystemViewClient) DefaultLeaseTTL() time.Duration { + reply, err := s.client.DefaultLeaseTTL(context.Background(), &pb.Empty{}) + if err != nil { + return 0 + } + + return time.Duration(reply.TTL) +} + +func (s *gRPCSystemViewClient) MaxLeaseTTL() time.Duration { + reply, err := s.client.MaxLeaseTTL(context.Background(), &pb.Empty{}) + if err != nil { + return 0 + } + + return time.Duration(reply.TTL) +} + +func (s *gRPCSystemViewClient) SudoPrivilege(path string, token string) bool { + reply, err := s.client.SudoPrivilege(context.Background(), &pb.SudoPrivilegeArgs{ + Path: path, + Token: token, + }) + if err != nil { + return false + } + + return reply.Sudo +} + +func (s *gRPCSystemViewClient) Tainted() bool { + reply, err := s.client.Tainted(context.Background(), &pb.Empty{}) + if err != nil { + return false + } + + return reply.Tainted +} + +func (s *gRPCSystemViewClient) CachingDisabled() bool { + reply, err := s.client.CachingDisabled(context.Background(), &pb.Empty{}) + if err != nil { + return false + } + + return reply.Disabled +} + +func (s *gRPCSystemViewClient) ReplicationState() consts.ReplicationState { + reply, err := s.client.ReplicationState(context.Background(), &pb.Empty{}) + if err != nil { + return consts.ReplicationDisabled + } + + return consts.ReplicationState(reply.State) +} + +func (s *gRPCSystemViewClient) ResponseWrapData(data map[string]interface{}, ttl time.Duration, jwt bool) (*wrapping.ResponseWrapInfo, error) { + buf, err := json.Marshal(data) + if err != nil { + return nil, err + } + + reply, err := s.client.ResponseWrapData(context.Background(), &pb.ResponseWrapDataArgs{ + Data: buf, + TTL: int64(ttl), + JWT: false, + }) + if err != nil { + return nil, err + } + if reply.Err != "" { + return nil, errors.New(reply.Err) + } + + // TODO: + return nil, nil +} + +func (s *gRPCSystemViewClient) LookupPlugin(name string) (*pluginutil.PluginRunner, error) { + return nil, fmt.Errorf("cannot call LookupPlugin from a plugin backend") +} + +func (s *gRPCSystemViewClient) MlockEnabled() bool { + reply, err := s.client.MlockEnabled(context.Background(), &pb.Empty{}) + if err != nil { + return false + } + + return reply.Enabled +} + +type gRPCSystemViewServer struct { + impl logical.SystemView +} + +func (s *gRPCSystemViewServer) DefaultLeaseTTL(ctx context.Context, _ *pb.Empty) (*pb.TTLReply, error) { + ttl := s.impl.DefaultLeaseTTL() + return &pb.TTLReply{ + TTL: int64(ttl), + }, nil +} + +func (s *gRPCSystemViewServer) MaxLeaseTTL(ctx context.Context, _ *pb.Empty) (*pb.TTLReply, error) { + ttl := s.impl.MaxLeaseTTL() + return &pb.TTLReply{ + TTL: int64(ttl), + }, nil +} + +func (s *gRPCSystemViewServer) SudoPrivilege(ctx context.Context, args *pb.SudoPrivilegeArgs) (*pb.SudoPrivilegeReply, error) { + sudo := s.impl.SudoPrivilege(args.Path, args.Token) + return &pb.SudoPrivilegeReply{ + Sudo: sudo, + }, nil +} + +func (s *gRPCSystemViewServer) Tainted(ctx context.Context, _ *pb.Empty) (*pb.TaintedReply, error) { + tainted := s.impl.Tainted() + return &pb.TaintedReply{ + Tainted: tainted, + }, nil +} + +func (s *gRPCSystemViewServer) CachingDisabled(ctx context.Context, _ *pb.Empty) (*pb.CachingDisabledReply, error) { + cachingDisabled := s.impl.CachingDisabled() + return &pb.CachingDisabledReply{ + Disabled: cachingDisabled, + }, nil +} + +func (s *gRPCSystemViewServer) ReplicationState(ctx context.Context, _ *pb.Empty) (*pb.ReplicationStateReply, error) { + replicationState := s.impl.ReplicationState() + return &pb.ReplicationStateReply{ + State: int32(replicationState), + }, nil +} + +func (s *gRPCSystemViewServer) ResponseWrapData(ctx context.Context, args *pb.ResponseWrapDataArgs) (*pb.ResponseWrapDataReply, error) { + data := map[string]interface{}{} + err := json.Unmarshal(args.Data, &data) + if err != nil { + return nil, err + } + + // Do not allow JWTs to be returned + _, err = s.impl.ResponseWrapData(data, time.Duration(args.TTL), false) + if err != nil { + return &pb.ResponseWrapDataReply{ + Err: pb.ErrToString(err), + }, nil + } + // TODO: + return &pb.ResponseWrapDataReply{ + // ResponseWrapInfo: info, + }, nil +} + +func (s *gRPCSystemViewServer) MlockEnabled(ctx context.Context, _ *pb.Empty) (*pb.MlockEnabledReply, error) { + enabled := s.impl.MlockEnabled() + return &pb.MlockEnabledReply{ + Enabled: enabled, + }, nil +} diff --git a/logical/plugin/pb/backend.pb.go b/logical/plugin/pb/backend.pb.go new file mode 100644 index 000000000000..38e97330ff3b --- /dev/null +++ b/logical/plugin/pb/backend.pb.go @@ -0,0 +1,2177 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: backend.proto + +/* +Package pb is a generated protocol buffer package. + +It is generated from these files: + backend.proto + +It has these top-level messages: + Empty + Header + Paths + Request + Alias + Auth + LeaseOptions + Secret + Response + HandleRequestArgs + HandleRequestReply + SpecialPathsReply + HandleExistenceCheckArgs + HandleExistenceCheckReply + SetupArgs + SetupReply + TypeReply + InvalidateKeyArgs + RegisterLicenseArgs + RegisterLicenseReply + StorageEntry + StorageListArgs + StorageListReply + StorageGetArgs + StorageGetReply + StoragePutArgs + StoragePutReply + StorageDeleteArgs + StorageDeleteReply + TTLReply + SudoPrivilegeArgs + SudoPrivilegeReply + TaintedReply + CachingDisabledReply + ReplicationStateReply + ResponseWrapDataArgs + ResponseWrapDataReply + MlockEnabledReply +*/ +package pb + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import google_protobuf "github.com/golang/protobuf/ptypes/timestamp" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type Empty struct { +} + +func (m *Empty) Reset() { *m = Empty{} } +func (m *Empty) String() string { return proto.CompactTextString(m) } +func (*Empty) ProtoMessage() {} +func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +type Header struct { + Header []string `protobuf:"bytes,1,rep,name=header" json:"header,omitempty"` +} + +func (m *Header) Reset() { *m = Header{} } +func (m *Header) String() string { return proto.CompactTextString(m) } +func (*Header) ProtoMessage() {} +func (*Header) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *Header) GetHeader() []string { + if m != nil { + return m.Header + } + return nil +} + +// Paths is the structure of special paths that is used for SpecialPaths. +type Paths struct { + // Root are the paths that require a root token to access + Root []string `protobuf:"bytes,1,rep,name=root" json:"root,omitempty"` + // Unauthenticated are the paths that can be accessed without any auth. + Unauthenticated []string `protobuf:"bytes,2,rep,name=unauthenticated" json:"unauthenticated,omitempty"` + // LocalStorage are paths (prefixes) that are local to this instance; this + // indicates that these paths should not be replicated + LocalStorage []string `protobuf:"bytes,3,rep,name=local_storage,json=localStorage" json:"local_storage,omitempty"` + // SealWrapStorage are storage paths that, when using a capable seal, + // should be seal wrapped with extra encryption. It is exact matching + // unless it ends with '/' in which case it will be treated as a prefix. + SealWrapStorage []string `protobuf:"bytes,4,rep,name=seal_wrap_storage,json=sealWrapStorage" json:"seal_wrap_storage,omitempty"` +} + +func (m *Paths) Reset() { *m = Paths{} } +func (m *Paths) String() string { return proto.CompactTextString(m) } +func (*Paths) ProtoMessage() {} +func (*Paths) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *Paths) GetRoot() []string { + if m != nil { + return m.Root + } + return nil +} + +func (m *Paths) GetUnauthenticated() []string { + if m != nil { + return m.Unauthenticated + } + return nil +} + +func (m *Paths) GetLocalStorage() []string { + if m != nil { + return m.LocalStorage + } + return nil +} + +func (m *Paths) GetSealWrapStorage() []string { + if m != nil { + return m.SealWrapStorage + } + return nil +} + +type Request struct { + // Id is the uuid associated with each request + Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` + // If set, the name given to the replication secondary where this request + // originated + ReplicationCluster string `protobuf:"bytes,2,opt,name=ReplicationCluster" json:"ReplicationCluster,omitempty"` + // Operation is the requested operation type + Operation string `protobuf:"bytes,3,opt,name=operation" json:"operation,omitempty"` + // Path is the part of the request path not consumed by the + // routing. As an example, if the original request path is "prod/aws/foo" + // and the AWS logical backend is mounted at "prod/aws/", then the + // final path is "foo" since the mount prefix is trimmed. + Path string `protobuf:"bytes,4,opt,name=path" json:"path,omitempty"` + // Request data is an opaque map that must have string keys. + Data []byte `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"` + // Secret will be non-nil only for Revoke and Renew operations + // to represent the secret that was returned prior. + Secret *Secret `protobuf:"bytes,6,opt,name=secret" json:"secret,omitempty"` + // Auth will be non-nil only for Renew operations + // to represent the auth that was returned prior. + Auth *Auth `protobuf:"bytes,7,opt,name=auth" json:"auth,omitempty"` + // Headers will contain the http headers from the request. This value will + // be used in the audit broker to ensure we are auditing only the allowed + // headers. + Headers map[string]*Header `protobuf:"bytes,8,rep,name=headers" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // ClientToken is provided to the core so that the identity + // can be verified and ACLs applied. This value is passed + // through to the logical backends but after being salted and + // hashed. + ClientToken string `protobuf:"bytes,9,opt,name=client_token,json=clientToken" json:"client_token,omitempty"` + // ClientTokenAccessor is provided to the core so that the it can get + // logged as part of request audit logging. + ClientTokenAccessor string `protobuf:"bytes,10,opt,name=client_token_accessor,json=clientTokenAccessor" json:"client_token_accessor,omitempty"` + // DisplayName is provided to the logical backend to help associate + // dynamic secrets with the source entity. This is not a sensitive + // name, but is useful for operators. + DisplayName string `protobuf:"bytes,11,opt,name=display_name,json=displayName" json:"display_name,omitempty"` + // MountPoint is provided so that a logical backend can generate + // paths relative to itself. The `Path` is effectively the client + // request path with the MountPoint trimmed off. + MountPoint string `protobuf:"bytes,12,opt,name=mount_point,json=mountPoint" json:"mount_point,omitempty"` + // MountType is provided so that a logical backend can make decisions + // based on the specific mount type (e.g., if a mount type has different + // aliases, generating different defaults depending on the alias) + MountType string `protobuf:"bytes,13,opt,name=mount_type,json=mountType" json:"mount_type,omitempty"` + // MountAccessor is provided so that identities returned by the authentication + // backends can be tied to the mount it belongs to. + MountAccessor string `protobuf:"bytes,14,opt,name=mount_accessor,json=mountAccessor" json:"mount_accessor,omitempty"` + // ClientTokenRemainingUses represents the allowed number of uses left on the + // token supplied + ClientTokenRemainingUses int64 `protobuf:"varint,16,opt,name=client_token_remaining_uses,json=clientTokenRemainingUses" json:"client_token_remaining_uses,omitempty"` + // EntityID is the identity of the caller extracted out of the token used + // to make this request + EntityId string `protobuf:"bytes,17,opt,name=entity_id,json=entityId" json:"entity_id,omitempty"` + // PolicyOverride indicates that the requestor wishes to override + // soft-mandatory Sentinel policies + PolicyOverride bool `protobuf:"varint,18,opt,name=policy_override,json=policyOverride" json:"policy_override,omitempty"` + // Whether the request is unauthenticated, as in, had no client token + // attached. Useful in some situations where the client token is not made + // accessible. + Unauthenticated bool `protobuf:"varint,19,opt,name=unauthenticated" json:"unauthenticated,omitempty"` +} + +func (m *Request) Reset() { *m = Request{} } +func (m *Request) String() string { return proto.CompactTextString(m) } +func (*Request) ProtoMessage() {} +func (*Request) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + +func (m *Request) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +func (m *Request) GetReplicationCluster() string { + if m != nil { + return m.ReplicationCluster + } + return "" +} + +func (m *Request) GetOperation() string { + if m != nil { + return m.Operation + } + return "" +} + +func (m *Request) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +func (m *Request) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *Request) GetSecret() *Secret { + if m != nil { + return m.Secret + } + return nil +} + +func (m *Request) GetAuth() *Auth { + if m != nil { + return m.Auth + } + return nil +} + +func (m *Request) GetHeaders() map[string]*Header { + if m != nil { + return m.Headers + } + return nil +} + +func (m *Request) GetClientToken() string { + if m != nil { + return m.ClientToken + } + return "" +} + +func (m *Request) GetClientTokenAccessor() string { + if m != nil { + return m.ClientTokenAccessor + } + return "" +} + +func (m *Request) GetDisplayName() string { + if m != nil { + return m.DisplayName + } + return "" +} + +func (m *Request) GetMountPoint() string { + if m != nil { + return m.MountPoint + } + return "" +} + +func (m *Request) GetMountType() string { + if m != nil { + return m.MountType + } + return "" +} + +func (m *Request) GetMountAccessor() string { + if m != nil { + return m.MountAccessor + } + return "" +} + +func (m *Request) GetClientTokenRemainingUses() int64 { + if m != nil { + return m.ClientTokenRemainingUses + } + return 0 +} + +func (m *Request) GetEntityId() string { + if m != nil { + return m.EntityId + } + return "" +} + +func (m *Request) GetPolicyOverride() bool { + if m != nil { + return m.PolicyOverride + } + return false +} + +func (m *Request) GetUnauthenticated() bool { + if m != nil { + return m.Unauthenticated + } + return false +} + +type Alias struct { + // MountType is the backend mount's type to which this identity belongs + MountType string `protobuf:"bytes,1,opt,name=mount_type,json=mountType" json:"mount_type,omitempty"` + // MountAccessor is the identifier of the mount entry to which this + // identity belongs + MountAccessor string `protobuf:"bytes,2,opt,name=mount_accessor,json=mountAccessor" json:"mount_accessor,omitempty"` + // Name is the identifier of this identity in its authentication source + Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` +} + +func (m *Alias) Reset() { *m = Alias{} } +func (m *Alias) String() string { return proto.CompactTextString(m) } +func (*Alias) ProtoMessage() {} +func (*Alias) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } + +func (m *Alias) GetMountType() string { + if m != nil { + return m.MountType + } + return "" +} + +func (m *Alias) GetMountAccessor() string { + if m != nil { + return m.MountAccessor + } + return "" +} + +func (m *Alias) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +type Auth struct { + LeaseOptions *LeaseOptions `protobuf:"bytes,1,opt,name=lease_options,json=leaseOptions" json:"lease_options,omitempty"` + // InternalData is JSON-encodable data that is stored with the auth struct. + // This will be sent back during a Renew/Revoke for storing internal data + // used for those operations. + InternalData []byte `protobuf:"bytes,2,opt,name=internal_data,json=internalData,proto3" json:"internal_data,omitempty"` + // DisplayName is a non-security sensitive identifier that is + // applicable to this Auth. It is used for logging and prefixing + // of dynamic secrets. For example, DisplayName may be "armon" for + // the github credential backend. If the client token is used to + // generate a SQL credential, the user may be "github-armon-uuid". + // This is to help identify the source without using audit tables. + DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName" json:"display_name,omitempty"` + // Policies is the list of policies that the authenticated user + // is associated with. + Policies []string `protobuf:"bytes,4,rep,name=policies" json:"policies,omitempty"` + // Metadata is used to attach arbitrary string-type metadata to + // an authenticated user. This metadata will be outputted into the + // audit log. + Metadata map[string]string `protobuf:"bytes,5,rep,name=metadata" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // ClientToken is the token that is generated for the authentication. + // This will be filled in by Vault core when an auth structure is + // returned. Setting this manually will have no effect. + ClientToken string `protobuf:"bytes,6,opt,name=client_token,json=clientToken" json:"client_token,omitempty"` + // Accessor is the identifier for the ClientToken. This can be used + // to perform management functionalities (especially revocation) when + // ClientToken in the audit logs are obfuscated. Accessor can be used + // to revoke a ClientToken and to lookup the capabilities of the ClientToken, + // both without actually knowing the ClientToken. + Accessor string `protobuf:"bytes,7,opt,name=accessor" json:"accessor,omitempty"` + // Period indicates that the token generated using this Auth object + // should never expire. The token should be renewed within the duration + // specified by this period. + Period int64 `protobuf:"varint,8,opt,name=period" json:"period,omitempty"` + // Number of allowed uses of the issued token + NumUses int64 `protobuf:"varint,9,opt,name=num_uses,json=numUses" json:"num_uses,omitempty"` + // EntityID is the identifier of the entity in identity store to which the + // identity of the authenticating client belongs to. + EntityId string `protobuf:"bytes,10,opt,name=entity_id,json=entityId" json:"entity_id,omitempty"` + // Alias is the information about the authenticated client returned by + // the auth backend + Alias *Alias `protobuf:"bytes,11,opt,name=alias" json:"alias,omitempty"` + // GroupAliases are the informational mappings of external groups which an + // authenticated user belongs to. This is used to check if there are + // mappings groups for the group aliases in identity store. For all the + // matching groups, the entity ID of the user will be added. + GroupAliases []*Alias `protobuf:"bytes,12,rep,name=group_aliases,json=groupAliases" json:"group_aliases,omitempty"` +} + +func (m *Auth) Reset() { *m = Auth{} } +func (m *Auth) String() string { return proto.CompactTextString(m) } +func (*Auth) ProtoMessage() {} +func (*Auth) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } + +func (m *Auth) GetLeaseOptions() *LeaseOptions { + if m != nil { + return m.LeaseOptions + } + return nil +} + +func (m *Auth) GetInternalData() []byte { + if m != nil { + return m.InternalData + } + return nil +} + +func (m *Auth) GetDisplayName() string { + if m != nil { + return m.DisplayName + } + return "" +} + +func (m *Auth) GetPolicies() []string { + if m != nil { + return m.Policies + } + return nil +} + +func (m *Auth) GetMetadata() map[string]string { + if m != nil { + return m.Metadata + } + return nil +} + +func (m *Auth) GetClientToken() string { + if m != nil { + return m.ClientToken + } + return "" +} + +func (m *Auth) GetAccessor() string { + if m != nil { + return m.Accessor + } + return "" +} + +func (m *Auth) GetPeriod() int64 { + if m != nil { + return m.Period + } + return 0 +} + +func (m *Auth) GetNumUses() int64 { + if m != nil { + return m.NumUses + } + return 0 +} + +func (m *Auth) GetEntityId() string { + if m != nil { + return m.EntityId + } + return "" +} + +func (m *Auth) GetAlias() *Alias { + if m != nil { + return m.Alias + } + return nil +} + +func (m *Auth) GetGroupAliases() []*Alias { + if m != nil { + return m.GroupAliases + } + return nil +} + +type LeaseOptions struct { + TTL int64 `protobuf:"varint,1,opt,name=TTL" json:"TTL,omitempty"` + Renewable bool `protobuf:"varint,2,opt,name=renewable" json:"renewable,omitempty"` + Increment int64 `protobuf:"varint,3,opt,name=increment" json:"increment,omitempty"` + IssueTime *google_protobuf.Timestamp `protobuf:"bytes,4,opt,name=issue_time,json=issueTime" json:"issue_time,omitempty"` +} + +func (m *LeaseOptions) Reset() { *m = LeaseOptions{} } +func (m *LeaseOptions) String() string { return proto.CompactTextString(m) } +func (*LeaseOptions) ProtoMessage() {} +func (*LeaseOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } + +func (m *LeaseOptions) GetTTL() int64 { + if m != nil { + return m.TTL + } + return 0 +} + +func (m *LeaseOptions) GetRenewable() bool { + if m != nil { + return m.Renewable + } + return false +} + +func (m *LeaseOptions) GetIncrement() int64 { + if m != nil { + return m.Increment + } + return 0 +} + +func (m *LeaseOptions) GetIssueTime() *google_protobuf.Timestamp { + if m != nil { + return m.IssueTime + } + return nil +} + +type Secret struct { + LeaseOptions *LeaseOptions `protobuf:"bytes,1,opt,name=lease_options,json=leaseOptions" json:"lease_options,omitempty"` + // InternalData is JSON-encodable data that is stored with the secret. + // This will be sent back during a Renew/Revoke for storing internal data + // used for those operations. + InternalData []byte `protobuf:"bytes,2,opt,name=internal_data,json=internalData,proto3" json:"internal_data,omitempty"` + // LeaseID is the ID returned to the user to manage this secret. + // This is generated by Vault core. Any set value will be ignored. + // For requests, this will always be blank. + LeaseId string `protobuf:"bytes,3,opt,name=lease_id,json=leaseId" json:"lease_id,omitempty"` +} + +func (m *Secret) Reset() { *m = Secret{} } +func (m *Secret) String() string { return proto.CompactTextString(m) } +func (*Secret) ProtoMessage() {} +func (*Secret) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } + +func (m *Secret) GetLeaseOptions() *LeaseOptions { + if m != nil { + return m.LeaseOptions + } + return nil +} + +func (m *Secret) GetInternalData() []byte { + if m != nil { + return m.InternalData + } + return nil +} + +func (m *Secret) GetLeaseId() string { + if m != nil { + return m.LeaseId + } + return "" +} + +type Response struct { + // Secret, if not nil, denotes that this response represents a secret. + Secret *Secret `protobuf:"bytes,1,opt,name=secret" json:"secret,omitempty"` + // Auth, if not nil, contains the authentication information for + // this response. This is only checked and means something for + // credential backends. + Auth *Auth `protobuf:"bytes,2,opt,name=auth" json:"auth,omitempty"` + // Response data is an opaque map that must have string keys. For + // secrets, this data is sent down to the user as-is. To store internal + // data that you don't want the user to see, store it in + // Secret.InternalData. + Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + // Redirect is an HTTP URL to redirect to for further authentication. + // This is only valid for credential backends. This will be blanked + // for any logical backend and ignored. + Redirect string `protobuf:"bytes,4,opt,name=redirect" json:"redirect,omitempty"` + // Warnings allow operations or backends to return warnings in response + // to user actions without failing the action outright. + Warnings []string `protobuf:"bytes,5,rep,name=warnings" json:"warnings,omitempty"` +} + +func (m *Response) Reset() { *m = Response{} } +func (m *Response) String() string { return proto.CompactTextString(m) } +func (*Response) ProtoMessage() {} +func (*Response) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } + +func (m *Response) GetSecret() *Secret { + if m != nil { + return m.Secret + } + return nil +} + +func (m *Response) GetAuth() *Auth { + if m != nil { + return m.Auth + } + return nil +} + +func (m *Response) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *Response) GetRedirect() string { + if m != nil { + return m.Redirect + } + return "" +} + +func (m *Response) GetWarnings() []string { + if m != nil { + return m.Warnings + } + return nil +} + +// HandleRequestArgs is the args for HandleRequest method. +type HandleRequestArgs struct { + StorageId uint32 `protobuf:"varint,1,opt,name=storage_id,json=storageId" json:"storage_id,omitempty"` + Request *Request `protobuf:"bytes,2,opt,name=request" json:"request,omitempty"` +} + +func (m *HandleRequestArgs) Reset() { *m = HandleRequestArgs{} } +func (m *HandleRequestArgs) String() string { return proto.CompactTextString(m) } +func (*HandleRequestArgs) ProtoMessage() {} +func (*HandleRequestArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } + +func (m *HandleRequestArgs) GetStorageId() uint32 { + if m != nil { + return m.StorageId + } + return 0 +} + +func (m *HandleRequestArgs) GetRequest() *Request { + if m != nil { + return m.Request + } + return nil +} + +// HandleRequestReply is the reply for HandleRequest method. +type HandleRequestReply struct { + Response *Response `protobuf:"bytes,1,opt,name=response" json:"response,omitempty"` + Err string `protobuf:"bytes,2,opt,name=err" json:"err,omitempty"` +} + +func (m *HandleRequestReply) Reset() { *m = HandleRequestReply{} } +func (m *HandleRequestReply) String() string { return proto.CompactTextString(m) } +func (*HandleRequestReply) ProtoMessage() {} +func (*HandleRequestReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } + +func (m *HandleRequestReply) GetResponse() *Response { + if m != nil { + return m.Response + } + return nil +} + +func (m *HandleRequestReply) GetErr() string { + if m != nil { + return m.Err + } + return "" +} + +// SpecialPathsReply is the reply for SpecialPaths method. +type SpecialPathsReply struct { + Paths *Paths `protobuf:"bytes,1,opt,name=paths" json:"paths,omitempty"` +} + +func (m *SpecialPathsReply) Reset() { *m = SpecialPathsReply{} } +func (m *SpecialPathsReply) String() string { return proto.CompactTextString(m) } +func (*SpecialPathsReply) ProtoMessage() {} +func (*SpecialPathsReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } + +func (m *SpecialPathsReply) GetPaths() *Paths { + if m != nil { + return m.Paths + } + return nil +} + +// HandleExistenceCheckArgs is the args for HandleExistenceCheck method. +type HandleExistenceCheckArgs struct { + StorageId uint32 `protobuf:"varint,1,opt,name=storage_id,json=storageId" json:"storage_id,omitempty"` + Request *Request `protobuf:"bytes,2,opt,name=request" json:"request,omitempty"` +} + +func (m *HandleExistenceCheckArgs) Reset() { *m = HandleExistenceCheckArgs{} } +func (m *HandleExistenceCheckArgs) String() string { return proto.CompactTextString(m) } +func (*HandleExistenceCheckArgs) ProtoMessage() {} +func (*HandleExistenceCheckArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } + +func (m *HandleExistenceCheckArgs) GetStorageId() uint32 { + if m != nil { + return m.StorageId + } + return 0 +} + +func (m *HandleExistenceCheckArgs) GetRequest() *Request { + if m != nil { + return m.Request + } + return nil +} + +// HandleExistenceCheckReply is the reply for HandleExistenceCheck method. +type HandleExistenceCheckReply struct { + CheckFound bool `protobuf:"varint,1,opt,name=check_found,json=checkFound" json:"check_found,omitempty"` + Exists bool `protobuf:"varint,2,opt,name=exists" json:"exists,omitempty"` + Err string `protobuf:"bytes,3,opt,name=err" json:"err,omitempty"` +} + +func (m *HandleExistenceCheckReply) Reset() { *m = HandleExistenceCheckReply{} } +func (m *HandleExistenceCheckReply) String() string { return proto.CompactTextString(m) } +func (*HandleExistenceCheckReply) ProtoMessage() {} +func (*HandleExistenceCheckReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } + +func (m *HandleExistenceCheckReply) GetCheckFound() bool { + if m != nil { + return m.CheckFound + } + return false +} + +func (m *HandleExistenceCheckReply) GetExists() bool { + if m != nil { + return m.Exists + } + return false +} + +func (m *HandleExistenceCheckReply) GetErr() string { + if m != nil { + return m.Err + } + return "" +} + +// SetupArgs is the args for Setup method. +type SetupArgs struct { + BrokerId uint32 `protobuf:"varint,1,opt,name=broker_id,json=brokerId" json:"broker_id,omitempty"` + Config map[string]string `protobuf:"bytes,2,rep,name=Config" json:"Config,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` +} + +func (m *SetupArgs) Reset() { *m = SetupArgs{} } +func (m *SetupArgs) String() string { return proto.CompactTextString(m) } +func (*SetupArgs) ProtoMessage() {} +func (*SetupArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } + +func (m *SetupArgs) GetBrokerId() uint32 { + if m != nil { + return m.BrokerId + } + return 0 +} + +func (m *SetupArgs) GetConfig() map[string]string { + if m != nil { + return m.Config + } + return nil +} + +// SetupReply is the reply for Setup method. +type SetupReply struct { + Err string `protobuf:"bytes,1,opt,name=err" json:"err,omitempty"` +} + +func (m *SetupReply) Reset() { *m = SetupReply{} } +func (m *SetupReply) String() string { return proto.CompactTextString(m) } +func (*SetupReply) ProtoMessage() {} +func (*SetupReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } + +func (m *SetupReply) GetErr() string { + if m != nil { + return m.Err + } + return "" +} + +// TypeReply is the reply for the Type method. +type TypeReply struct { + Type uint32 `protobuf:"varint,1,opt,name=type" json:"type,omitempty"` +} + +func (m *TypeReply) Reset() { *m = TypeReply{} } +func (m *TypeReply) String() string { return proto.CompactTextString(m) } +func (*TypeReply) ProtoMessage() {} +func (*TypeReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } + +func (m *TypeReply) GetType() uint32 { + if m != nil { + return m.Type + } + return 0 +} + +type InvalidateKeyArgs struct { + Key string `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"` +} + +func (m *InvalidateKeyArgs) Reset() { *m = InvalidateKeyArgs{} } +func (m *InvalidateKeyArgs) String() string { return proto.CompactTextString(m) } +func (*InvalidateKeyArgs) ProtoMessage() {} +func (*InvalidateKeyArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } + +func (m *InvalidateKeyArgs) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +// RegisterLicenseArgs is the args for the RegisterLicense method. +type RegisterLicenseArgs struct { +} + +func (m *RegisterLicenseArgs) Reset() { *m = RegisterLicenseArgs{} } +func (m *RegisterLicenseArgs) String() string { return proto.CompactTextString(m) } +func (*RegisterLicenseArgs) ProtoMessage() {} +func (*RegisterLicenseArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } + +// RegisterLicenseReply is the reply for the RegisterLicense method. +type RegisterLicenseReply struct { + Err string `protobuf:"bytes,1,opt,name=err" json:"err,omitempty"` +} + +func (m *RegisterLicenseReply) Reset() { *m = RegisterLicenseReply{} } +func (m *RegisterLicenseReply) String() string { return proto.CompactTextString(m) } +func (*RegisterLicenseReply) ProtoMessage() {} +func (*RegisterLicenseReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } + +func (m *RegisterLicenseReply) GetErr() string { + if m != nil { + return m.Err + } + return "" +} + +type StorageEntry struct { + Key string `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + SealWrap bool `protobuf:"varint,3,opt,name=seal_wrap,json=sealWrap" json:"seal_wrap,omitempty"` +} + +func (m *StorageEntry) Reset() { *m = StorageEntry{} } +func (m *StorageEntry) String() string { return proto.CompactTextString(m) } +func (*StorageEntry) ProtoMessage() {} +func (*StorageEntry) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } + +func (m *StorageEntry) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +func (m *StorageEntry) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func (m *StorageEntry) GetSealWrap() bool { + if m != nil { + return m.SealWrap + } + return false +} + +type StorageListArgs struct { + Prefix string `protobuf:"bytes,1,opt,name=prefix" json:"prefix,omitempty"` +} + +func (m *StorageListArgs) Reset() { *m = StorageListArgs{} } +func (m *StorageListArgs) String() string { return proto.CompactTextString(m) } +func (*StorageListArgs) ProtoMessage() {} +func (*StorageListArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } + +func (m *StorageListArgs) GetPrefix() string { + if m != nil { + return m.Prefix + } + return "" +} + +type StorageListReply struct { + Keys []string `protobuf:"bytes,1,rep,name=keys" json:"keys,omitempty"` + Err string `protobuf:"bytes,2,opt,name=err" json:"err,omitempty"` +} + +func (m *StorageListReply) Reset() { *m = StorageListReply{} } +func (m *StorageListReply) String() string { return proto.CompactTextString(m) } +func (*StorageListReply) ProtoMessage() {} +func (*StorageListReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } + +func (m *StorageListReply) GetKeys() []string { + if m != nil { + return m.Keys + } + return nil +} + +func (m *StorageListReply) GetErr() string { + if m != nil { + return m.Err + } + return "" +} + +type StorageGetArgs struct { + Key string `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"` +} + +func (m *StorageGetArgs) Reset() { *m = StorageGetArgs{} } +func (m *StorageGetArgs) String() string { return proto.CompactTextString(m) } +func (*StorageGetArgs) ProtoMessage() {} +func (*StorageGetArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } + +func (m *StorageGetArgs) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +type StorageGetReply struct { + Entry *StorageEntry `protobuf:"bytes,1,opt,name=entry" json:"entry,omitempty"` + Err string `protobuf:"bytes,2,opt,name=err" json:"err,omitempty"` +} + +func (m *StorageGetReply) Reset() { *m = StorageGetReply{} } +func (m *StorageGetReply) String() string { return proto.CompactTextString(m) } +func (*StorageGetReply) ProtoMessage() {} +func (*StorageGetReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } + +func (m *StorageGetReply) GetEntry() *StorageEntry { + if m != nil { + return m.Entry + } + return nil +} + +func (m *StorageGetReply) GetErr() string { + if m != nil { + return m.Err + } + return "" +} + +type StoragePutArgs struct { + Entry *StorageEntry `protobuf:"bytes,1,opt,name=entry" json:"entry,omitempty"` +} + +func (m *StoragePutArgs) Reset() { *m = StoragePutArgs{} } +func (m *StoragePutArgs) String() string { return proto.CompactTextString(m) } +func (*StoragePutArgs) ProtoMessage() {} +func (*StoragePutArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } + +func (m *StoragePutArgs) GetEntry() *StorageEntry { + if m != nil { + return m.Entry + } + return nil +} + +type StoragePutReply struct { + Err string `protobuf:"bytes,1,opt,name=err" json:"err,omitempty"` +} + +func (m *StoragePutReply) Reset() { *m = StoragePutReply{} } +func (m *StoragePutReply) String() string { return proto.CompactTextString(m) } +func (*StoragePutReply) ProtoMessage() {} +func (*StoragePutReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} } + +func (m *StoragePutReply) GetErr() string { + if m != nil { + return m.Err + } + return "" +} + +type StorageDeleteArgs struct { + Key string `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"` +} + +func (m *StorageDeleteArgs) Reset() { *m = StorageDeleteArgs{} } +func (m *StorageDeleteArgs) String() string { return proto.CompactTextString(m) } +func (*StorageDeleteArgs) ProtoMessage() {} +func (*StorageDeleteArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} } + +func (m *StorageDeleteArgs) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +type StorageDeleteReply struct { + Err string `protobuf:"bytes,1,opt,name=err" json:"err,omitempty"` +} + +func (m *StorageDeleteReply) Reset() { *m = StorageDeleteReply{} } +func (m *StorageDeleteReply) String() string { return proto.CompactTextString(m) } +func (*StorageDeleteReply) ProtoMessage() {} +func (*StorageDeleteReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} } + +func (m *StorageDeleteReply) GetErr() string { + if m != nil { + return m.Err + } + return "" +} + +type TTLReply struct { + TTL int64 `protobuf:"varint,1,opt,name=TTL" json:"TTL,omitempty"` +} + +func (m *TTLReply) Reset() { *m = TTLReply{} } +func (m *TTLReply) String() string { return proto.CompactTextString(m) } +func (*TTLReply) ProtoMessage() {} +func (*TTLReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} } + +func (m *TTLReply) GetTTL() int64 { + if m != nil { + return m.TTL + } + return 0 +} + +type SudoPrivilegeArgs struct { + Path string `protobuf:"bytes,1,opt,name=path" json:"path,omitempty"` + Token string `protobuf:"bytes,2,opt,name=token" json:"token,omitempty"` +} + +func (m *SudoPrivilegeArgs) Reset() { *m = SudoPrivilegeArgs{} } +func (m *SudoPrivilegeArgs) String() string { return proto.CompactTextString(m) } +func (*SudoPrivilegeArgs) ProtoMessage() {} +func (*SudoPrivilegeArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} } + +func (m *SudoPrivilegeArgs) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +func (m *SudoPrivilegeArgs) GetToken() string { + if m != nil { + return m.Token + } + return "" +} + +type SudoPrivilegeReply struct { + Sudo bool `protobuf:"varint,1,opt,name=sudo" json:"sudo,omitempty"` +} + +func (m *SudoPrivilegeReply) Reset() { *m = SudoPrivilegeReply{} } +func (m *SudoPrivilegeReply) String() string { return proto.CompactTextString(m) } +func (*SudoPrivilegeReply) ProtoMessage() {} +func (*SudoPrivilegeReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} } + +func (m *SudoPrivilegeReply) GetSudo() bool { + if m != nil { + return m.Sudo + } + return false +} + +type TaintedReply struct { + Tainted bool `protobuf:"varint,1,opt,name=tainted" json:"tainted,omitempty"` +} + +func (m *TaintedReply) Reset() { *m = TaintedReply{} } +func (m *TaintedReply) String() string { return proto.CompactTextString(m) } +func (*TaintedReply) ProtoMessage() {} +func (*TaintedReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} } + +func (m *TaintedReply) GetTainted() bool { + if m != nil { + return m.Tainted + } + return false +} + +type CachingDisabledReply struct { + Disabled bool `protobuf:"varint,1,opt,name=disabled" json:"disabled,omitempty"` +} + +func (m *CachingDisabledReply) Reset() { *m = CachingDisabledReply{} } +func (m *CachingDisabledReply) String() string { return proto.CompactTextString(m) } +func (*CachingDisabledReply) ProtoMessage() {} +func (*CachingDisabledReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} } + +func (m *CachingDisabledReply) GetDisabled() bool { + if m != nil { + return m.Disabled + } + return false +} + +type ReplicationStateReply struct { + State int32 `protobuf:"varint,1,opt,name=state" json:"state,omitempty"` +} + +func (m *ReplicationStateReply) Reset() { *m = ReplicationStateReply{} } +func (m *ReplicationStateReply) String() string { return proto.CompactTextString(m) } +func (*ReplicationStateReply) ProtoMessage() {} +func (*ReplicationStateReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} } + +func (m *ReplicationStateReply) GetState() int32 { + if m != nil { + return m.State + } + return 0 +} + +type ResponseWrapDataArgs struct { + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + TTL int64 `protobuf:"varint,2,opt,name=TTL" json:"TTL,omitempty"` + JWT bool `protobuf:"varint,3,opt,name=JWT" json:"JWT,omitempty"` +} + +func (m *ResponseWrapDataArgs) Reset() { *m = ResponseWrapDataArgs{} } +func (m *ResponseWrapDataArgs) String() string { return proto.CompactTextString(m) } +func (*ResponseWrapDataArgs) ProtoMessage() {} +func (*ResponseWrapDataArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} } + +func (m *ResponseWrapDataArgs) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *ResponseWrapDataArgs) GetTTL() int64 { + if m != nil { + return m.TTL + } + return 0 +} + +func (m *ResponseWrapDataArgs) GetJWT() bool { + if m != nil { + return m.JWT + } + return false +} + +type ResponseWrapDataReply struct { + // WrapInfo info = 1; + Err string `protobuf:"bytes,2,opt,name=err" json:"err,omitempty"` +} + +func (m *ResponseWrapDataReply) Reset() { *m = ResponseWrapDataReply{} } +func (m *ResponseWrapDataReply) String() string { return proto.CompactTextString(m) } +func (*ResponseWrapDataReply) ProtoMessage() {} +func (*ResponseWrapDataReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} } + +func (m *ResponseWrapDataReply) GetErr() string { + if m != nil { + return m.Err + } + return "" +} + +type MlockEnabledReply struct { + Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"` +} + +func (m *MlockEnabledReply) Reset() { *m = MlockEnabledReply{} } +func (m *MlockEnabledReply) String() string { return proto.CompactTextString(m) } +func (*MlockEnabledReply) ProtoMessage() {} +func (*MlockEnabledReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} } + +func (m *MlockEnabledReply) GetEnabled() bool { + if m != nil { + return m.Enabled + } + return false +} + +func init() { + proto.RegisterType((*Empty)(nil), "pb.Empty") + proto.RegisterType((*Header)(nil), "pb.Header") + proto.RegisterType((*Paths)(nil), "pb.Paths") + proto.RegisterType((*Request)(nil), "pb.Request") + proto.RegisterType((*Alias)(nil), "pb.Alias") + proto.RegisterType((*Auth)(nil), "pb.Auth") + proto.RegisterType((*LeaseOptions)(nil), "pb.LeaseOptions") + proto.RegisterType((*Secret)(nil), "pb.Secret") + proto.RegisterType((*Response)(nil), "pb.Response") + proto.RegisterType((*HandleRequestArgs)(nil), "pb.HandleRequestArgs") + proto.RegisterType((*HandleRequestReply)(nil), "pb.HandleRequestReply") + proto.RegisterType((*SpecialPathsReply)(nil), "pb.SpecialPathsReply") + proto.RegisterType((*HandleExistenceCheckArgs)(nil), "pb.HandleExistenceCheckArgs") + proto.RegisterType((*HandleExistenceCheckReply)(nil), "pb.HandleExistenceCheckReply") + proto.RegisterType((*SetupArgs)(nil), "pb.SetupArgs") + proto.RegisterType((*SetupReply)(nil), "pb.SetupReply") + proto.RegisterType((*TypeReply)(nil), "pb.TypeReply") + proto.RegisterType((*InvalidateKeyArgs)(nil), "pb.InvalidateKeyArgs") + proto.RegisterType((*RegisterLicenseArgs)(nil), "pb.RegisterLicenseArgs") + proto.RegisterType((*RegisterLicenseReply)(nil), "pb.RegisterLicenseReply") + proto.RegisterType((*StorageEntry)(nil), "pb.StorageEntry") + proto.RegisterType((*StorageListArgs)(nil), "pb.StorageListArgs") + proto.RegisterType((*StorageListReply)(nil), "pb.StorageListReply") + proto.RegisterType((*StorageGetArgs)(nil), "pb.StorageGetArgs") + proto.RegisterType((*StorageGetReply)(nil), "pb.StorageGetReply") + proto.RegisterType((*StoragePutArgs)(nil), "pb.StoragePutArgs") + proto.RegisterType((*StoragePutReply)(nil), "pb.StoragePutReply") + proto.RegisterType((*StorageDeleteArgs)(nil), "pb.StorageDeleteArgs") + proto.RegisterType((*StorageDeleteReply)(nil), "pb.StorageDeleteReply") + proto.RegisterType((*TTLReply)(nil), "pb.TTLReply") + proto.RegisterType((*SudoPrivilegeArgs)(nil), "pb.SudoPrivilegeArgs") + proto.RegisterType((*SudoPrivilegeReply)(nil), "pb.SudoPrivilegeReply") + proto.RegisterType((*TaintedReply)(nil), "pb.TaintedReply") + proto.RegisterType((*CachingDisabledReply)(nil), "pb.CachingDisabledReply") + proto.RegisterType((*ReplicationStateReply)(nil), "pb.ReplicationStateReply") + proto.RegisterType((*ResponseWrapDataArgs)(nil), "pb.ResponseWrapDataArgs") + proto.RegisterType((*ResponseWrapDataReply)(nil), "pb.ResponseWrapDataReply") + proto.RegisterType((*MlockEnabledReply)(nil), "pb.MlockEnabledReply") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// Client API for Backend service + +type BackendClient interface { + HandleRequest(ctx context.Context, in *HandleRequestArgs, opts ...grpc.CallOption) (*HandleRequestReply, error) + SpecialPaths(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*SpecialPathsReply, error) + HandleExistenceCheck(ctx context.Context, in *HandleExistenceCheckArgs, opts ...grpc.CallOption) (*HandleExistenceCheckReply, error) + Initialize(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) + Cleanup(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) + InvalidateKey(ctx context.Context, in *InvalidateKeyArgs, opts ...grpc.CallOption) (*Empty, error) + Setup(ctx context.Context, in *SetupArgs, opts ...grpc.CallOption) (*SetupReply, error) + Type(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TypeReply, error) + RegisterLicense(ctx context.Context, in *RegisterLicenseArgs, opts ...grpc.CallOption) (*RegisterLicenseReply, error) +} + +type backendClient struct { + cc *grpc.ClientConn +} + +func NewBackendClient(cc *grpc.ClientConn) BackendClient { + return &backendClient{cc} +} + +func (c *backendClient) HandleRequest(ctx context.Context, in *HandleRequestArgs, opts ...grpc.CallOption) (*HandleRequestReply, error) { + out := new(HandleRequestReply) + err := grpc.Invoke(ctx, "/pb.Backend/HandleRequest", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *backendClient) SpecialPaths(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*SpecialPathsReply, error) { + out := new(SpecialPathsReply) + err := grpc.Invoke(ctx, "/pb.Backend/SpecialPaths", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *backendClient) HandleExistenceCheck(ctx context.Context, in *HandleExistenceCheckArgs, opts ...grpc.CallOption) (*HandleExistenceCheckReply, error) { + out := new(HandleExistenceCheckReply) + err := grpc.Invoke(ctx, "/pb.Backend/HandleExistenceCheck", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *backendClient) Initialize(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := grpc.Invoke(ctx, "/pb.Backend/Initialize", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *backendClient) Cleanup(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := grpc.Invoke(ctx, "/pb.Backend/Cleanup", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *backendClient) InvalidateKey(ctx context.Context, in *InvalidateKeyArgs, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := grpc.Invoke(ctx, "/pb.Backend/InvalidateKey", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *backendClient) Setup(ctx context.Context, in *SetupArgs, opts ...grpc.CallOption) (*SetupReply, error) { + out := new(SetupReply) + err := grpc.Invoke(ctx, "/pb.Backend/Setup", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *backendClient) Type(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TypeReply, error) { + out := new(TypeReply) + err := grpc.Invoke(ctx, "/pb.Backend/Type", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *backendClient) RegisterLicense(ctx context.Context, in *RegisterLicenseArgs, opts ...grpc.CallOption) (*RegisterLicenseReply, error) { + out := new(RegisterLicenseReply) + err := grpc.Invoke(ctx, "/pb.Backend/RegisterLicense", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for Backend service + +type BackendServer interface { + HandleRequest(context.Context, *HandleRequestArgs) (*HandleRequestReply, error) + SpecialPaths(context.Context, *Empty) (*SpecialPathsReply, error) + HandleExistenceCheck(context.Context, *HandleExistenceCheckArgs) (*HandleExistenceCheckReply, error) + Initialize(context.Context, *Empty) (*Empty, error) + Cleanup(context.Context, *Empty) (*Empty, error) + InvalidateKey(context.Context, *InvalidateKeyArgs) (*Empty, error) + Setup(context.Context, *SetupArgs) (*SetupReply, error) + Type(context.Context, *Empty) (*TypeReply, error) + RegisterLicense(context.Context, *RegisterLicenseArgs) (*RegisterLicenseReply, error) +} + +func RegisterBackendServer(s *grpc.Server, srv BackendServer) { + s.RegisterService(&_Backend_serviceDesc, srv) +} + +func _Backend_HandleRequest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HandleRequestArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BackendServer).HandleRequest(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Backend/HandleRequest", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BackendServer).HandleRequest(ctx, req.(*HandleRequestArgs)) + } + return interceptor(ctx, in, info, handler) +} + +func _Backend_SpecialPaths_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BackendServer).SpecialPaths(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Backend/SpecialPaths", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BackendServer).SpecialPaths(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Backend_HandleExistenceCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HandleExistenceCheckArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BackendServer).HandleExistenceCheck(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Backend/HandleExistenceCheck", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BackendServer).HandleExistenceCheck(ctx, req.(*HandleExistenceCheckArgs)) + } + return interceptor(ctx, in, info, handler) +} + +func _Backend_Initialize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BackendServer).Initialize(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Backend/Initialize", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BackendServer).Initialize(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Backend_Cleanup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BackendServer).Cleanup(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Backend/Cleanup", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BackendServer).Cleanup(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Backend_InvalidateKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InvalidateKeyArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BackendServer).InvalidateKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Backend/InvalidateKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BackendServer).InvalidateKey(ctx, req.(*InvalidateKeyArgs)) + } + return interceptor(ctx, in, info, handler) +} + +func _Backend_Setup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetupArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BackendServer).Setup(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Backend/Setup", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BackendServer).Setup(ctx, req.(*SetupArgs)) + } + return interceptor(ctx, in, info, handler) +} + +func _Backend_Type_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BackendServer).Type(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Backend/Type", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BackendServer).Type(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _Backend_RegisterLicense_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegisterLicenseArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BackendServer).RegisterLicense(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Backend/RegisterLicense", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BackendServer).RegisterLicense(ctx, req.(*RegisterLicenseArgs)) + } + return interceptor(ctx, in, info, handler) +} + +var _Backend_serviceDesc = grpc.ServiceDesc{ + ServiceName: "pb.Backend", + HandlerType: (*BackendServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "HandleRequest", + Handler: _Backend_HandleRequest_Handler, + }, + { + MethodName: "SpecialPaths", + Handler: _Backend_SpecialPaths_Handler, + }, + { + MethodName: "HandleExistenceCheck", + Handler: _Backend_HandleExistenceCheck_Handler, + }, + { + MethodName: "Initialize", + Handler: _Backend_Initialize_Handler, + }, + { + MethodName: "Cleanup", + Handler: _Backend_Cleanup_Handler, + }, + { + MethodName: "InvalidateKey", + Handler: _Backend_InvalidateKey_Handler, + }, + { + MethodName: "Setup", + Handler: _Backend_Setup_Handler, + }, + { + MethodName: "Type", + Handler: _Backend_Type_Handler, + }, + { + MethodName: "RegisterLicense", + Handler: _Backend_RegisterLicense_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "backend.proto", +} + +// Client API for Storage service + +type StorageClient interface { + List(ctx context.Context, in *StorageListArgs, opts ...grpc.CallOption) (*StorageListReply, error) + Get(ctx context.Context, in *StorageGetArgs, opts ...grpc.CallOption) (*StorageGetReply, error) + Put(ctx context.Context, in *StoragePutArgs, opts ...grpc.CallOption) (*StoragePutReply, error) + Delete(ctx context.Context, in *StorageDeleteArgs, opts ...grpc.CallOption) (*StorageDeleteReply, error) +} + +type storageClient struct { + cc *grpc.ClientConn +} + +func NewStorageClient(cc *grpc.ClientConn) StorageClient { + return &storageClient{cc} +} + +func (c *storageClient) List(ctx context.Context, in *StorageListArgs, opts ...grpc.CallOption) (*StorageListReply, error) { + out := new(StorageListReply) + err := grpc.Invoke(ctx, "/pb.Storage/List", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *storageClient) Get(ctx context.Context, in *StorageGetArgs, opts ...grpc.CallOption) (*StorageGetReply, error) { + out := new(StorageGetReply) + err := grpc.Invoke(ctx, "/pb.Storage/Get", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *storageClient) Put(ctx context.Context, in *StoragePutArgs, opts ...grpc.CallOption) (*StoragePutReply, error) { + out := new(StoragePutReply) + err := grpc.Invoke(ctx, "/pb.Storage/Put", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *storageClient) Delete(ctx context.Context, in *StorageDeleteArgs, opts ...grpc.CallOption) (*StorageDeleteReply, error) { + out := new(StorageDeleteReply) + err := grpc.Invoke(ctx, "/pb.Storage/Delete", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for Storage service + +type StorageServer interface { + List(context.Context, *StorageListArgs) (*StorageListReply, error) + Get(context.Context, *StorageGetArgs) (*StorageGetReply, error) + Put(context.Context, *StoragePutArgs) (*StoragePutReply, error) + Delete(context.Context, *StorageDeleteArgs) (*StorageDeleteReply, error) +} + +func RegisterStorageServer(s *grpc.Server, srv StorageServer) { + s.RegisterService(&_Storage_serviceDesc, srv) +} + +func _Storage_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StorageListArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StorageServer).List(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Storage/List", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StorageServer).List(ctx, req.(*StorageListArgs)) + } + return interceptor(ctx, in, info, handler) +} + +func _Storage_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StorageGetArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StorageServer).Get(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Storage/Get", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StorageServer).Get(ctx, req.(*StorageGetArgs)) + } + return interceptor(ctx, in, info, handler) +} + +func _Storage_Put_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StoragePutArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StorageServer).Put(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Storage/Put", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StorageServer).Put(ctx, req.(*StoragePutArgs)) + } + return interceptor(ctx, in, info, handler) +} + +func _Storage_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StorageDeleteArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StorageServer).Delete(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Storage/Delete", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StorageServer).Delete(ctx, req.(*StorageDeleteArgs)) + } + return interceptor(ctx, in, info, handler) +} + +var _Storage_serviceDesc = grpc.ServiceDesc{ + ServiceName: "pb.Storage", + HandlerType: (*StorageServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "List", + Handler: _Storage_List_Handler, + }, + { + MethodName: "Get", + Handler: _Storage_Get_Handler, + }, + { + MethodName: "Put", + Handler: _Storage_Put_Handler, + }, + { + MethodName: "Delete", + Handler: _Storage_Delete_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "backend.proto", +} + +// Client API for SystemView service + +type SystemViewClient interface { + DefaultLeaseTTL(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TTLReply, error) + MaxLeaseTTL(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TTLReply, error) + SudoPrivilege(ctx context.Context, in *SudoPrivilegeArgs, opts ...grpc.CallOption) (*SudoPrivilegeReply, error) + Tainted(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TaintedReply, error) + CachingDisabled(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*CachingDisabledReply, error) + ReplicationState(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ReplicationStateReply, error) + ResponseWrapData(ctx context.Context, in *ResponseWrapDataArgs, opts ...grpc.CallOption) (*ResponseWrapDataReply, error) + MlockEnabled(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*MlockEnabledReply, error) +} + +type systemViewClient struct { + cc *grpc.ClientConn +} + +func NewSystemViewClient(cc *grpc.ClientConn) SystemViewClient { + return &systemViewClient{cc} +} + +func (c *systemViewClient) DefaultLeaseTTL(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TTLReply, error) { + out := new(TTLReply) + err := grpc.Invoke(ctx, "/pb.SystemView/DefaultLeaseTTL", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *systemViewClient) MaxLeaseTTL(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TTLReply, error) { + out := new(TTLReply) + err := grpc.Invoke(ctx, "/pb.SystemView/MaxLeaseTTL", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *systemViewClient) SudoPrivilege(ctx context.Context, in *SudoPrivilegeArgs, opts ...grpc.CallOption) (*SudoPrivilegeReply, error) { + out := new(SudoPrivilegeReply) + err := grpc.Invoke(ctx, "/pb.SystemView/SudoPrivilege", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *systemViewClient) Tainted(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TaintedReply, error) { + out := new(TaintedReply) + err := grpc.Invoke(ctx, "/pb.SystemView/Tainted", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *systemViewClient) CachingDisabled(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*CachingDisabledReply, error) { + out := new(CachingDisabledReply) + err := grpc.Invoke(ctx, "/pb.SystemView/CachingDisabled", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *systemViewClient) ReplicationState(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ReplicationStateReply, error) { + out := new(ReplicationStateReply) + err := grpc.Invoke(ctx, "/pb.SystemView/ReplicationState", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *systemViewClient) ResponseWrapData(ctx context.Context, in *ResponseWrapDataArgs, opts ...grpc.CallOption) (*ResponseWrapDataReply, error) { + out := new(ResponseWrapDataReply) + err := grpc.Invoke(ctx, "/pb.SystemView/ResponseWrapData", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *systemViewClient) MlockEnabled(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*MlockEnabledReply, error) { + out := new(MlockEnabledReply) + err := grpc.Invoke(ctx, "/pb.SystemView/MlockEnabled", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for SystemView service + +type SystemViewServer interface { + DefaultLeaseTTL(context.Context, *Empty) (*TTLReply, error) + MaxLeaseTTL(context.Context, *Empty) (*TTLReply, error) + SudoPrivilege(context.Context, *SudoPrivilegeArgs) (*SudoPrivilegeReply, error) + Tainted(context.Context, *Empty) (*TaintedReply, error) + CachingDisabled(context.Context, *Empty) (*CachingDisabledReply, error) + ReplicationState(context.Context, *Empty) (*ReplicationStateReply, error) + ResponseWrapData(context.Context, *ResponseWrapDataArgs) (*ResponseWrapDataReply, error) + MlockEnabled(context.Context, *Empty) (*MlockEnabledReply, error) +} + +func RegisterSystemViewServer(s *grpc.Server, srv SystemViewServer) { + s.RegisterService(&_SystemView_serviceDesc, srv) +} + +func _SystemView_DefaultLeaseTTL_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SystemViewServer).DefaultLeaseTTL(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.SystemView/DefaultLeaseTTL", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SystemViewServer).DefaultLeaseTTL(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _SystemView_MaxLeaseTTL_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SystemViewServer).MaxLeaseTTL(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.SystemView/MaxLeaseTTL", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SystemViewServer).MaxLeaseTTL(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _SystemView_SudoPrivilege_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SudoPrivilegeArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SystemViewServer).SudoPrivilege(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.SystemView/SudoPrivilege", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SystemViewServer).SudoPrivilege(ctx, req.(*SudoPrivilegeArgs)) + } + return interceptor(ctx, in, info, handler) +} + +func _SystemView_Tainted_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SystemViewServer).Tainted(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.SystemView/Tainted", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SystemViewServer).Tainted(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _SystemView_CachingDisabled_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SystemViewServer).CachingDisabled(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.SystemView/CachingDisabled", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SystemViewServer).CachingDisabled(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _SystemView_ReplicationState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SystemViewServer).ReplicationState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.SystemView/ReplicationState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SystemViewServer).ReplicationState(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _SystemView_ResponseWrapData_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResponseWrapDataArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SystemViewServer).ResponseWrapData(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.SystemView/ResponseWrapData", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SystemViewServer).ResponseWrapData(ctx, req.(*ResponseWrapDataArgs)) + } + return interceptor(ctx, in, info, handler) +} + +func _SystemView_MlockEnabled_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SystemViewServer).MlockEnabled(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.SystemView/MlockEnabled", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SystemViewServer).MlockEnabled(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +var _SystemView_serviceDesc = grpc.ServiceDesc{ + ServiceName: "pb.SystemView", + HandlerType: (*SystemViewServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "DefaultLeaseTTL", + Handler: _SystemView_DefaultLeaseTTL_Handler, + }, + { + MethodName: "MaxLeaseTTL", + Handler: _SystemView_MaxLeaseTTL_Handler, + }, + { + MethodName: "SudoPrivilege", + Handler: _SystemView_SudoPrivilege_Handler, + }, + { + MethodName: "Tainted", + Handler: _SystemView_Tainted_Handler, + }, + { + MethodName: "CachingDisabled", + Handler: _SystemView_CachingDisabled_Handler, + }, + { + MethodName: "ReplicationState", + Handler: _SystemView_ReplicationState_Handler, + }, + { + MethodName: "ResponseWrapData", + Handler: _SystemView_ResponseWrapData_Handler, + }, + { + MethodName: "MlockEnabled", + Handler: _SystemView_MlockEnabled_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "backend.proto", +} + +func init() { proto.RegisterFile("backend.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 1836 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xef, 0x6e, 0xe3, 0xc6, + 0x11, 0x07, 0x25, 0x4b, 0xa2, 0x46, 0x92, 0xff, 0xec, 0xf9, 0xae, 0xb4, 0xee, 0x52, 0xab, 0x0c, + 0xce, 0x55, 0x02, 0x44, 0xc9, 0xa9, 0xff, 0x2e, 0x2d, 0x12, 0xc0, 0xb5, 0x2f, 0x17, 0x37, 0xbe, + 0xc4, 0xa0, 0xd4, 0x06, 0xfd, 0xa4, 0xae, 0xc5, 0xb1, 0xbc, 0x30, 0x45, 0xb2, 0xe4, 0xf2, 0xee, + 0xd4, 0x2f, 0x7d, 0x8b, 0xb4, 0x2f, 0xd2, 0x47, 0x29, 0xd0, 0x2f, 0x7d, 0x89, 0x3e, 0x41, 0xb1, + 0xb3, 0x4b, 0x8a, 0xfa, 0x63, 0x5c, 0x0a, 0x34, 0xdf, 0x76, 0x7e, 0x33, 0x3b, 0x3b, 0x3b, 0x9c, + 0xf9, 0xcd, 0x12, 0x3a, 0xd7, 0x7c, 0x7a, 0x87, 0xa1, 0x3f, 0x88, 0x93, 0x48, 0x46, 0xac, 0x12, + 0x5f, 0x77, 0x8f, 0x67, 0x51, 0x34, 0x0b, 0xf0, 0x63, 0x42, 0xae, 0xb3, 0x9b, 0x8f, 0xa5, 0x98, + 0x63, 0x2a, 0xf9, 0x3c, 0xd6, 0x46, 0x6e, 0x03, 0x6a, 0x2f, 0xe6, 0xb1, 0x5c, 0xb8, 0x3d, 0xa8, + 0x7f, 0x89, 0xdc, 0xc7, 0x84, 0x3d, 0x82, 0xfa, 0x2d, 0xad, 0x1c, 0xab, 0x57, 0xed, 0x37, 0x3d, + 0x23, 0xb9, 0xdf, 0x59, 0x50, 0xbb, 0xe2, 0xf2, 0x36, 0x65, 0x0c, 0x76, 0x92, 0x28, 0x92, 0x46, + 0x4f, 0x6b, 0xd6, 0x87, 0xbd, 0x2c, 0xe4, 0x99, 0xbc, 0xc5, 0x50, 0x8a, 0x29, 0x97, 0xe8, 0x3b, + 0x15, 0x52, 0xaf, 0xc3, 0xec, 0x7d, 0xe8, 0x04, 0xd1, 0x94, 0x07, 0x93, 0x54, 0x46, 0x09, 0x9f, + 0xa1, 0x53, 0x25, 0xbb, 0x36, 0x81, 0x23, 0x8d, 0xb1, 0x0f, 0xe1, 0x20, 0x45, 0x1e, 0x4c, 0xde, + 0x24, 0x3c, 0x2e, 0x0c, 0x77, 0xb4, 0x43, 0xa5, 0xf8, 0x36, 0xe1, 0xb1, 0xb1, 0x75, 0xff, 0x5d, + 0x83, 0x86, 0x87, 0x7f, 0xce, 0x30, 0x95, 0x6c, 0x17, 0x2a, 0xc2, 0x77, 0xac, 0x9e, 0xd5, 0x6f, + 0x7a, 0x15, 0xe1, 0xb3, 0x01, 0x30, 0x0f, 0xe3, 0x40, 0x1d, 0x2d, 0xa2, 0xf0, 0x2c, 0xc8, 0x52, + 0x89, 0x89, 0x53, 0x21, 0xfd, 0x16, 0x0d, 0x7b, 0x02, 0xcd, 0x28, 0xc6, 0x84, 0x30, 0xa7, 0x4a, + 0x66, 0x4b, 0x40, 0x5d, 0x3c, 0xe6, 0xf2, 0xd6, 0xd9, 0x21, 0x05, 0xad, 0x15, 0xe6, 0x73, 0xc9, + 0x9d, 0x5a, 0xcf, 0xea, 0xb7, 0x3d, 0x5a, 0x33, 0x17, 0xea, 0x29, 0x4e, 0x13, 0x94, 0x4e, 0xbd, + 0x67, 0xf5, 0x5b, 0x43, 0x18, 0xc4, 0xd7, 0x83, 0x11, 0x21, 0x9e, 0xd1, 0xb0, 0x27, 0xb0, 0xa3, + 0xf2, 0xe2, 0x34, 0xc8, 0xc2, 0x56, 0x16, 0xa7, 0x99, 0xbc, 0xf5, 0x08, 0x65, 0x43, 0x68, 0xe8, + 0xb4, 0xa7, 0x8e, 0xdd, 0xab, 0xf6, 0x5b, 0x43, 0x47, 0x19, 0x98, 0x5b, 0x0e, 0xf4, 0x97, 0x4a, + 0x5f, 0x84, 0x32, 0x59, 0x78, 0xb9, 0x21, 0xfb, 0x09, 0xb4, 0xa7, 0x81, 0xc0, 0x50, 0x4e, 0x64, + 0x74, 0x87, 0xa1, 0xd3, 0xa4, 0x28, 0x5b, 0x1a, 0x1b, 0x2b, 0x88, 0x0d, 0xe1, 0x61, 0xd9, 0x64, + 0xc2, 0xa7, 0x53, 0x4c, 0xd3, 0x28, 0x71, 0x80, 0x6c, 0x1f, 0x94, 0x6c, 0x4f, 0x8d, 0x4a, 0xb9, + 0xf5, 0x45, 0x1a, 0x07, 0x7c, 0x31, 0x09, 0xf9, 0x1c, 0x9d, 0x96, 0x76, 0x6b, 0xb0, 0xaf, 0xf9, + 0x1c, 0xd9, 0x31, 0xb4, 0xe6, 0x51, 0x16, 0xca, 0x49, 0x1c, 0x89, 0x50, 0x3a, 0x6d, 0xb2, 0x00, + 0x82, 0xae, 0x14, 0xc2, 0xde, 0x03, 0x2d, 0x4d, 0xe4, 0x22, 0x46, 0xa7, 0xa3, 0xf3, 0x4a, 0xc8, + 0x78, 0x11, 0x23, 0x7b, 0x0a, 0xbb, 0x5a, 0x5d, 0xc4, 0xb3, 0x4b, 0x26, 0x1d, 0x42, 0x8b, 0x48, + 0x3e, 0x83, 0xc7, 0x2b, 0xd1, 0x27, 0x38, 0xe7, 0x22, 0x14, 0xe1, 0x6c, 0x92, 0xa5, 0x98, 0x3a, + 0xfb, 0x3d, 0xab, 0x5f, 0xf5, 0x9c, 0xd2, 0x1d, 0xbc, 0xdc, 0xe0, 0xf7, 0x29, 0xa6, 0xec, 0x31, + 0x34, 0x55, 0x15, 0xca, 0xc5, 0x44, 0xf8, 0xce, 0x01, 0x1d, 0x60, 0x6b, 0xe0, 0xc2, 0x67, 0x3f, + 0x85, 0xbd, 0x38, 0x0a, 0xc4, 0x74, 0x31, 0x89, 0x5e, 0x63, 0x92, 0x08, 0x1f, 0x1d, 0xd6, 0xb3, + 0xfa, 0xb6, 0xb7, 0xab, 0xe1, 0x6f, 0x0c, 0xba, 0xad, 0xd0, 0x1f, 0x90, 0xe1, 0x3a, 0xdc, 0xfd, + 0x02, 0xda, 0xe5, 0x0f, 0xc5, 0xf6, 0xa1, 0x7a, 0x87, 0x0b, 0x53, 0x9c, 0x6a, 0xc9, 0x7a, 0x50, + 0x7b, 0xcd, 0x83, 0x0c, 0xa9, 0x20, 0x4d, 0x99, 0xe8, 0x2d, 0x9e, 0x56, 0xfc, 0xba, 0xf2, 0xdc, + 0x72, 0x39, 0xd4, 0x4e, 0x03, 0xc1, 0xd3, 0xb5, 0x2c, 0x5a, 0xef, 0xce, 0x62, 0x65, 0x5b, 0x16, + 0x19, 0xec, 0xd0, 0x77, 0xd4, 0xd5, 0x4d, 0x6b, 0xf7, 0x3f, 0x55, 0xd8, 0x51, 0xd5, 0xc7, 0x7e, + 0x01, 0x9d, 0x00, 0x79, 0x8a, 0x93, 0x28, 0x56, 0x15, 0x9f, 0xd2, 0x29, 0xad, 0xe1, 0xbe, 0x8a, + 0xec, 0x52, 0x29, 0xbe, 0xd1, 0xb8, 0xd7, 0x0e, 0x4a, 0x92, 0xea, 0x69, 0x11, 0x4a, 0x4c, 0x42, + 0x1e, 0x4c, 0xa8, 0x1b, 0x2a, 0xd4, 0x0d, 0xed, 0x1c, 0x3c, 0x57, 0x5d, 0xb1, 0x5e, 0x48, 0xd5, + 0xcd, 0x42, 0xea, 0x82, 0x4d, 0xe9, 0x16, 0x98, 0x9a, 0x6e, 0x2f, 0x64, 0x36, 0x04, 0x7b, 0x8e, + 0x92, 0x9b, 0x66, 0x53, 0x3d, 0xf1, 0x28, 0x6f, 0x9a, 0xc1, 0x2b, 0xa3, 0xd0, 0x1d, 0x51, 0xd8, + 0x6d, 0xb4, 0x44, 0x7d, 0xb3, 0x25, 0xba, 0x60, 0x17, 0xf9, 0x6a, 0xe8, 0xa2, 0xc8, 0x65, 0x45, + 0x85, 0x31, 0x26, 0x22, 0xf2, 0x1d, 0x9b, 0x6a, 0xcb, 0x48, 0xec, 0x08, 0xec, 0x30, 0x9b, 0xeb, + 0xaa, 0x6b, 0x92, 0xa6, 0x11, 0x66, 0xf3, 0xcd, 0x22, 0x83, 0xb5, 0x22, 0x3b, 0x86, 0x1a, 0x57, + 0x5f, 0x92, 0x7a, 0xa8, 0x35, 0x6c, 0x52, 0xfc, 0x0a, 0xf0, 0x34, 0xce, 0x06, 0xd0, 0x99, 0x25, + 0x51, 0x16, 0x4f, 0x48, 0xc4, 0xd4, 0x69, 0xd3, 0x45, 0x4b, 0x86, 0x6d, 0xd2, 0x9f, 0x6a, 0x75, + 0xf7, 0x37, 0xd0, 0x59, 0xb9, 0xfa, 0x96, 0x1a, 0x3b, 0x2c, 0xd7, 0x58, 0xb3, 0x5c, 0x57, 0x7f, + 0xb3, 0xa0, 0x5d, 0xfe, 0xa6, 0x6a, 0xf3, 0x78, 0x7c, 0x49, 0x9b, 0xab, 0x9e, 0x5a, 0x2a, 0x3a, + 0x4c, 0x30, 0xc4, 0x37, 0xfc, 0x3a, 0xd0, 0x0e, 0x6c, 0x6f, 0x09, 0x28, 0xad, 0x08, 0xa7, 0x09, + 0xce, 0x31, 0x94, 0xf4, 0x35, 0xab, 0xde, 0x12, 0x60, 0x9f, 0x02, 0x88, 0x34, 0xcd, 0x70, 0xa2, + 0x66, 0x0e, 0x51, 0x66, 0x6b, 0xd8, 0x1d, 0xe8, 0x81, 0x34, 0xc8, 0x07, 0xd2, 0x60, 0x9c, 0x0f, + 0x24, 0xaf, 0x49, 0xd6, 0x4a, 0x76, 0xff, 0x0a, 0x75, 0xcd, 0x96, 0x3f, 0x68, 0x3d, 0x1e, 0x81, + 0xad, 0x7d, 0x0b, 0xdf, 0xd4, 0x62, 0x83, 0xe4, 0x0b, 0xdf, 0xfd, 0xbb, 0x05, 0xb6, 0x87, 0x69, + 0x1c, 0x85, 0x29, 0x96, 0xd8, 0xdc, 0x7a, 0x27, 0x9b, 0x57, 0xb6, 0xb2, 0x79, 0x3e, 0x23, 0xaa, + 0xa5, 0x19, 0xd1, 0x05, 0x3b, 0x41, 0x5f, 0x24, 0x38, 0x95, 0x66, 0x9e, 0x14, 0xb2, 0xd2, 0xbd, + 0xe1, 0x89, 0x22, 0xae, 0x94, 0x4a, 0xbd, 0xe9, 0x15, 0xb2, 0xfb, 0x47, 0x38, 0xf8, 0x92, 0x87, + 0x7e, 0x80, 0x66, 0x18, 0x9c, 0x26, 0x33, 0x62, 0x06, 0x33, 0x24, 0x27, 0x66, 0xfc, 0x75, 0xbc, + 0xa6, 0x41, 0x2e, 0x7c, 0xf6, 0x14, 0x1a, 0x89, 0xb6, 0x36, 0x01, 0xb6, 0x4a, 0xd3, 0xc4, 0xcb, + 0x75, 0xee, 0x15, 0xb0, 0x15, 0xd7, 0x6a, 0x3e, 0x2e, 0x58, 0x5f, 0x05, 0xaa, 0x53, 0x61, 0x12, + 0xd0, 0xd6, 0xbb, 0x35, 0xe6, 0x15, 0x5a, 0x55, 0x3f, 0x98, 0xe4, 0xac, 0xa3, 0x96, 0xee, 0xcf, + 0xe1, 0x60, 0x14, 0xe3, 0x54, 0xf0, 0x80, 0x5e, 0x0e, 0xda, 0xe1, 0x31, 0xd4, 0xd4, 0xe4, 0xcc, + 0xbf, 0x25, 0x15, 0xb7, 0x56, 0x6b, 0xdc, 0xfd, 0x13, 0x38, 0x3a, 0x8e, 0x17, 0x6f, 0x45, 0x2a, + 0x31, 0x9c, 0xe2, 0xd9, 0x2d, 0x4e, 0xef, 0xfe, 0x8f, 0x37, 0xbd, 0x81, 0xa3, 0x6d, 0x27, 0xe4, + 0xf1, 0xb5, 0xa6, 0x4a, 0x9a, 0xdc, 0x44, 0x59, 0xa8, 0xcf, 0xb0, 0x3d, 0x20, 0xe8, 0x0b, 0x85, + 0x28, 0x5a, 0x40, 0xb5, 0x2f, 0x35, 0x2d, 0x61, 0xa4, 0xfc, 0xfe, 0xd5, 0xe5, 0xfd, 0xbf, 0xb3, + 0xa0, 0x39, 0x42, 0x99, 0xc5, 0x14, 0xfb, 0x63, 0x68, 0x5e, 0x27, 0xd1, 0x1d, 0x26, 0xcb, 0xd0, + 0x6d, 0x0d, 0x5c, 0xf8, 0xec, 0x19, 0xd4, 0xcf, 0xa2, 0xf0, 0x46, 0xcc, 0xe8, 0xdd, 0xd4, 0x1a, + 0x1e, 0xe9, 0x2a, 0x33, 0x7b, 0x07, 0x5a, 0xa7, 0xf9, 0xcd, 0x18, 0x76, 0x3f, 0x85, 0x56, 0x09, + 0xfe, 0x9f, 0x7a, 0xff, 0xc7, 0x00, 0xe4, 0x5b, 0xdf, 0xd8, 0x04, 0x6e, 0x2d, 0x03, 0x3f, 0x86, + 0xa6, 0x9a, 0x29, 0x5a, 0xcd, 0x60, 0xa7, 0x98, 0x38, 0x1d, 0x8f, 0xd6, 0xee, 0x53, 0x38, 0xb8, + 0x08, 0x5f, 0xf3, 0x40, 0xf8, 0x5c, 0xe2, 0x57, 0xb8, 0xa0, 0x0b, 0x6e, 0x44, 0xe0, 0x3e, 0x84, + 0x07, 0x1e, 0xce, 0x54, 0x8e, 0x93, 0x4b, 0x31, 0xc5, 0x30, 0x45, 0x65, 0xe8, 0xf6, 0xe1, 0x70, + 0x0d, 0xbe, 0x2f, 0x90, 0x11, 0xb4, 0xcd, 0x3b, 0xef, 0x7b, 0x5d, 0xb2, 0x6d, 0x2e, 0xa9, 0x72, + 0x5d, 0x3c, 0x20, 0xe9, 0x8b, 0xd8, 0x9e, 0x9d, 0x3f, 0x1c, 0xdd, 0x0f, 0x60, 0xcf, 0x38, 0xbd, + 0x14, 0xa6, 0x83, 0x14, 0xd5, 0x27, 0x78, 0x23, 0xde, 0x1a, 0xd7, 0x46, 0x72, 0x9f, 0xc3, 0x7e, + 0xc9, 0xb4, 0xc8, 0xc7, 0x1d, 0x2e, 0xd2, 0xfc, 0xfd, 0xab, 0xd6, 0x5b, 0x6a, 0xdf, 0x85, 0x5d, + 0xb3, 0xf3, 0x25, 0xca, 0x7b, 0xd2, 0xf3, 0x55, 0x11, 0xc8, 0x4b, 0x34, 0xce, 0x4f, 0xa0, 0x86, + 0xea, 0xa6, 0x65, 0xa6, 0x2b, 0x67, 0xc0, 0xd3, 0xea, 0x2d, 0x07, 0x3e, 0x2f, 0x0e, 0xbc, 0xca, + 0xf4, 0x81, 0xdf, 0xd3, 0x97, 0xfb, 0x7e, 0x11, 0xc6, 0x55, 0x26, 0xef, 0xfb, 0x12, 0x4f, 0xe1, + 0xc0, 0x18, 0x9d, 0x63, 0x80, 0x12, 0xef, 0xb9, 0xd2, 0x09, 0xb0, 0x15, 0xb3, 0xfb, 0xdc, 0x3d, + 0x01, 0x7b, 0x3c, 0xbe, 0x2c, 0xb4, 0xab, 0x83, 0xc7, 0xfd, 0x0c, 0x0e, 0x46, 0x99, 0x1f, 0x5d, + 0x25, 0xe2, 0xb5, 0x08, 0x70, 0xa6, 0x0f, 0xcb, 0x9f, 0xdf, 0x56, 0xe9, 0xf9, 0x7d, 0x08, 0x35, + 0x3d, 0xda, 0x4d, 0x89, 0x93, 0xe0, 0xf6, 0x81, 0xad, 0x6c, 0x2f, 0xbe, 0x5b, 0x9a, 0xf9, 0x91, + 0xe9, 0x68, 0x5a, 0xbb, 0x7d, 0x68, 0x8f, 0xb9, 0x1a, 0x0b, 0xbe, 0xb6, 0x71, 0xa0, 0x21, 0xb5, + 0x6c, 0xcc, 0x72, 0xd1, 0x1d, 0xc2, 0xe1, 0x19, 0x9f, 0xde, 0x8a, 0x70, 0x76, 0x2e, 0x52, 0x35, + 0xff, 0xcc, 0x8e, 0x2e, 0xd8, 0xbe, 0x01, 0xcc, 0x96, 0x42, 0x76, 0x3f, 0x82, 0x87, 0xa5, 0x9f, + 0x8c, 0x91, 0xe4, 0x79, 0x3e, 0x0e, 0xa1, 0x96, 0x2a, 0x89, 0x76, 0xd4, 0x3c, 0x2d, 0xb8, 0x5f, + 0xab, 0xb6, 0xd0, 0x64, 0xaa, 0xea, 0x54, 0x4d, 0xa9, 0xfc, 0xe2, 0x34, 0x3f, 0xac, 0xd2, 0xfc, + 0x30, 0x39, 0xab, 0x2c, 0x87, 0xf5, 0x3e, 0x54, 0x7f, 0xf7, 0xed, 0xd8, 0x14, 0xbb, 0x5a, 0xba, + 0x1f, 0xa8, 0xe3, 0x57, 0xfd, 0xad, 0x7c, 0x8e, 0x52, 0xf1, 0x7c, 0x04, 0x07, 0xaf, 0x82, 0x68, + 0x7a, 0xf7, 0x22, 0x2c, 0x5d, 0xcd, 0x81, 0x06, 0x86, 0xe5, 0x9b, 0xe5, 0xe2, 0xf0, 0x5f, 0x55, + 0x68, 0xfc, 0x56, 0xff, 0x6e, 0xb2, 0xcf, 0xa1, 0xb3, 0x32, 0x36, 0xd8, 0x43, 0x7a, 0xc7, 0xae, + 0x0f, 0xa9, 0xee, 0xa3, 0x0d, 0x58, 0x9f, 0xf2, 0x09, 0xb4, 0xcb, 0x43, 0x82, 0xd1, 0x40, 0xa0, + 0xbf, 0xd2, 0x2e, 0x79, 0xda, 0x9c, 0x20, 0x23, 0x38, 0xdc, 0x46, 0xdf, 0xec, 0xc9, 0xf2, 0x84, + 0xcd, 0xd1, 0xd1, 0x7d, 0xef, 0x3e, 0xad, 0x76, 0xea, 0x02, 0x5c, 0x84, 0x42, 0x0a, 0x1e, 0x88, + 0xbf, 0x60, 0x39, 0x88, 0xe5, 0x92, 0x1d, 0x43, 0xe3, 0x2c, 0x40, 0x1e, 0x66, 0xf1, 0x3d, 0x06, + 0xcf, 0xa0, 0xb3, 0x42, 0x8b, 0x3a, 0x17, 0x1b, 0x4c, 0x59, 0xde, 0x72, 0x02, 0x35, 0xa2, 0x62, + 0xd6, 0x59, 0x61, 0xfc, 0xee, 0x6e, 0x21, 0xea, 0xf8, 0x7a, 0xb0, 0x43, 0xcf, 0xfc, 0xd2, 0xc1, + 0xb4, 0x63, 0xc9, 0xd3, 0xe7, 0xb0, 0xb7, 0xc6, 0xaa, 0xec, 0x47, 0x7a, 0xfc, 0x6d, 0x30, 0x70, + 0xd7, 0xd9, 0xa2, 0x20, 0x2f, 0xc3, 0x7f, 0x5a, 0xd0, 0xc8, 0x7f, 0xc3, 0x9f, 0xc1, 0x8e, 0xa2, + 0x3d, 0xf6, 0xa0, 0xc4, 0x1c, 0x39, 0x65, 0x76, 0x0f, 0xd7, 0x40, 0x1d, 0xc4, 0x00, 0xaa, 0x2f, + 0x51, 0x32, 0x56, 0x52, 0x1a, 0xfe, 0xeb, 0x3e, 0x58, 0xc5, 0x0a, 0xfb, 0xab, 0x6c, 0xd5, 0xde, + 0xd0, 0xd7, 0x8a, 0x7d, 0x41, 0x4c, 0xbf, 0x82, 0xba, 0x26, 0x16, 0x9d, 0xda, 0x0d, 0x4a, 0xd2, + 0x65, 0xb6, 0x49, 0x41, 0xc3, 0x7f, 0x54, 0x01, 0x46, 0x8b, 0x54, 0xe2, 0xfc, 0x0f, 0x02, 0xdf, + 0xb0, 0x0f, 0x61, 0xef, 0x1c, 0x6f, 0x78, 0x16, 0x48, 0x7a, 0x47, 0xaa, 0x06, 0x2a, 0x65, 0x96, + 0x9e, 0x38, 0x05, 0x3f, 0x9d, 0x40, 0xeb, 0x15, 0x7f, 0xfb, 0x6e, 0xbb, 0xcf, 0xa1, 0xb3, 0x42, + 0x3b, 0x26, 0xc4, 0x75, 0x22, 0x33, 0x21, 0x6e, 0x12, 0xd4, 0x09, 0x34, 0x0c, 0x19, 0x95, 0xcf, + 0x20, 0xda, 0x5e, 0x21, 0xa9, 0x5f, 0xc2, 0xde, 0x1a, 0x15, 0x95, 0xed, 0xe9, 0xd3, 0x6e, 0xa5, + 0xaa, 0xe7, 0xb0, 0xbf, 0x4e, 0x47, 0xe5, 0x8d, 0x47, 0xba, 0x26, 0xb6, 0xf1, 0xd5, 0x4b, 0xb5, + 0x73, 0x95, 0x49, 0x98, 0x53, 0x7e, 0x06, 0x96, 0xf9, 0x2a, 0x77, 0xb4, 0x8d, 0x79, 0x3e, 0x81, + 0x76, 0x99, 0x67, 0x36, 0x9a, 0x7d, 0x83, 0x84, 0xae, 0xeb, 0xf4, 0xaf, 0xf0, 0xb3, 0xff, 0x06, + 0x00, 0x00, 0xff, 0xff, 0x25, 0xde, 0xdf, 0x88, 0xdf, 0x12, 0x00, 0x00, +} diff --git a/logical/plugin/pb/backend.proto b/logical/plugin/pb/backend.proto new file mode 100644 index 000000000000..c60b4a4f412e --- /dev/null +++ b/logical/plugin/pb/backend.proto @@ -0,0 +1,406 @@ +syntax = "proto3"; +package pb; + +import "google/protobuf/timestamp.proto"; + +message Empty {} + +message Header { + repeated string header = 1; +} + +// Paths is the structure of special paths that is used for SpecialPaths. +message Paths { + // Root are the paths that require a root token to access + repeated string root = 1; + + // Unauthenticated are the paths that can be accessed without any auth. + repeated string unauthenticated = 2; + + // LocalStorage are paths (prefixes) that are local to this instance; this + // indicates that these paths should not be replicated + repeated string local_storage = 3; + + // SealWrapStorage are storage paths that, when using a capable seal, + // should be seal wrapped with extra encryption. It is exact matching + // unless it ends with '/' in which case it will be treated as a prefix. + repeated string seal_wrap_storage = 4; +} + +message Request { + // Id is the uuid associated with each request + string id = 1; + + // If set, the name given to the replication secondary where this request + // originated + string ReplicationCluster = 2; + + // Operation is the requested operation type + string operation = 3; + + // Path is the part of the request path not consumed by the + // routing. As an example, if the original request path is "prod/aws/foo" + // and the AWS logical backend is mounted at "prod/aws/", then the + // final path is "foo" since the mount prefix is trimmed. + string path = 4; + + // Request data is an opaque map that must have string keys. + bytes data = 5; + + // Secret will be non-nil only for Revoke and Renew operations + // to represent the secret that was returned prior. + Secret secret = 6; + + // Auth will be non-nil only for Renew operations + // to represent the auth that was returned prior. + Auth auth = 7; + + // Headers will contain the http headers from the request. This value will + // be used in the audit broker to ensure we are auditing only the allowed + // headers. + map headers = 8; + + // ClientToken is provided to the core so that the identity + // can be verified and ACLs applied. This value is passed + // through to the logical backends but after being salted and + // hashed. + string client_token = 9; + + // ClientTokenAccessor is provided to the core so that the it can get + // logged as part of request audit logging. + string client_token_accessor = 10; + + // DisplayName is provided to the logical backend to help associate + // dynamic secrets with the source entity. This is not a sensitive + // name, but is useful for operators. + string display_name = 11; + + // MountPoint is provided so that a logical backend can generate + // paths relative to itself. The `Path` is effectively the client + // request path with the MountPoint trimmed off. + string mount_point = 12; + + // MountType is provided so that a logical backend can make decisions + // based on the specific mount type (e.g., if a mount type has different + // aliases, generating different defaults depending on the alias) + string mount_type = 13; + + // MountAccessor is provided so that identities returned by the authentication + // backends can be tied to the mount it belongs to. + string mount_accessor = 14; + + // WrapInfo contains requested response wrapping parameters +// WrapInfo *RequestWrapInfo `json:"wrap_info" structs:"wrap_info" mapstructure:"wrap_info" sentinel:""` + + // ClientTokenRemainingUses represents the allowed number of uses left on the + // token supplied + int64 client_token_remaining_uses = 16; + + // EntityID is the identity of the caller extracted out of the token used + // to make this request + string entity_id = 17; + + // PolicyOverride indicates that the requestor wishes to override + // soft-mandatory Sentinel policies + bool policy_override = 18; + + // Whether the request is unauthenticated, as in, had no client token + // attached. Useful in some situations where the client token is not made + // accessible. + bool unauthenticated = 19; +} + +message Alias { + // MountType is the backend mount's type to which this identity belongs + string mount_type = 1; + + // MountAccessor is the identifier of the mount entry to which this + // identity belongs + string mount_accessor = 2; + + // Name is the identifier of this identity in its authentication source + string name = 3; +} + +message Auth { + LeaseOptions lease_options = 1; + + // InternalData is JSON-encodable data that is stored with the auth struct. + // This will be sent back during a Renew/Revoke for storing internal data + // used for those operations. + bytes internal_data = 2; + + // DisplayName is a non-security sensitive identifier that is + // applicable to this Auth. It is used for logging and prefixing + // of dynamic secrets. For example, DisplayName may be "armon" for + // the github credential backend. If the client token is used to + // generate a SQL credential, the user may be "github-armon-uuid". + // This is to help identify the source without using audit tables. + string display_name = 3; + + // Policies is the list of policies that the authenticated user + // is associated with. + repeated string policies = 4; + + // Metadata is used to attach arbitrary string-type metadata to + // an authenticated user. This metadata will be outputted into the + // audit log. + map metadata = 5; + + // ClientToken is the token that is generated for the authentication. + // This will be filled in by Vault core when an auth structure is + // returned. Setting this manually will have no effect. + string client_token = 6; + + // Accessor is the identifier for the ClientToken. This can be used + // to perform management functionalities (especially revocation) when + // ClientToken in the audit logs are obfuscated. Accessor can be used + // to revoke a ClientToken and to lookup the capabilities of the ClientToken, + // both without actually knowing the ClientToken. + string accessor = 7; + + // Period indicates that the token generated using this Auth object + // should never expire. The token should be renewed within the duration + // specified by this period. + int64 period = 8; + + // Number of allowed uses of the issued token + int64 num_uses = 9; + + // EntityID is the identifier of the entity in identity store to which the + // identity of the authenticating client belongs to. + string entity_id = 10; + + // Alias is the information about the authenticated client returned by + // the auth backend + Alias alias = 11; + + // GroupAliases are the informational mappings of external groups which an + // authenticated user belongs to. This is used to check if there are + // mappings groups for the group aliases in identity store. For all the + // matching groups, the entity ID of the user will be added. + repeated Alias group_aliases = 12; +} + +message LeaseOptions { + int64 TTL = 1; + + bool renewable = 2; + + int64 increment = 3; + + google.protobuf.Timestamp issue_time = 4; +} + +message Secret { + LeaseOptions lease_options = 1; + + // InternalData is JSON-encodable data that is stored with the secret. + // This will be sent back during a Renew/Revoke for storing internal data + // used for those operations. + bytes internal_data = 2; + + // LeaseID is the ID returned to the user to manage this secret. + // This is generated by Vault core. Any set value will be ignored. + // For requests, this will always be blank. + string lease_id = 3; +} + +message Response { + // Secret, if not nil, denotes that this response represents a secret. + Secret secret = 1; + + // Auth, if not nil, contains the authentication information for + // this response. This is only checked and means something for + // credential backends. + Auth auth = 2; + + // Response data is an opaque map that must have string keys. For + // secrets, this data is sent down to the user as-is. To store internal + // data that you don't want the user to see, store it in + // Secret.InternalData. + bytes data = 3; + + // Redirect is an HTTP URL to redirect to for further authentication. + // This is only valid for credential backends. This will be blanked + // for any logical backend and ignored. + string redirect = 4; + + // Warnings allow operations or backends to return warnings in response + // to user actions without failing the action outright. + repeated string warnings = 5; + + // Information for wrapping the response in a cubbyhole + //WrapInfo *wrapping.ResponseWrapInfo `json:"wrap_info" structs:"wrap_info" mapstructure:"wrap_info"` +} + +// HandleRequestArgs is the args for HandleRequest method. +message HandleRequestArgs { + uint32 storage_id = 1; + Request request = 2; +} + +// HandleRequestReply is the reply for HandleRequest method. +message HandleRequestReply { + Response response = 1; + string err = 2; +} + +// SpecialPathsReply is the reply for SpecialPaths method. +message SpecialPathsReply { + Paths paths = 1; +} + +// HandleExistenceCheckArgs is the args for HandleExistenceCheck method. +message HandleExistenceCheckArgs { + uint32 storage_id = 1; + Request request = 2; +} + +// HandleExistenceCheckReply is the reply for HandleExistenceCheck method. +message HandleExistenceCheckReply { + bool check_found = 1; + bool exists = 2; + string err = 3; +} + +// SetupArgs is the args for Setup method. +message SetupArgs { + uint32 broker_id = 1; + map Config = 2; +} + +// SetupReply is the reply for Setup method. +message SetupReply { + string err = 1; +} + +// TypeReply is the reply for the Type method. +message TypeReply { + uint32 type = 1; +} + +message InvalidateKeyArgs { + string key = 1; +} + +// RegisterLicenseArgs is the args for the RegisterLicense method. +message RegisterLicenseArgs { +} + +// RegisterLicenseReply is the reply for the RegisterLicense method. +message RegisterLicenseReply { + string err = 1; +} + +service Backend { + rpc HandleRequest(HandleRequestArgs) returns (HandleRequestReply); + rpc SpecialPaths(Empty) returns (SpecialPathsReply); + rpc HandleExistenceCheck(HandleExistenceCheckArgs) returns (HandleExistenceCheckReply); + rpc Initialize(Empty) returns (Empty); + rpc Cleanup(Empty) returns (Empty); + rpc InvalidateKey(InvalidateKeyArgs) returns (Empty); + rpc Setup(SetupArgs) returns (SetupReply); + rpc Type(Empty) returns (TypeReply); + rpc RegisterLicense(RegisterLicenseArgs) returns (RegisterLicenseReply); +} + +message StorageEntry { + string key = 1; + bytes value = 2; + bool seal_wrap = 3; +} + +message StorageListArgs { + string prefix = 1; +} + +message StorageListReply { + repeated string keys = 1; + string err = 2; +} + +message StorageGetArgs { + string key = 1; +} + +message StorageGetReply { + StorageEntry entry = 1; + string err = 2; +} + +message StoragePutArgs { + StorageEntry entry = 1; +} + +message StoragePutReply { + string err = 1; +} + +message StorageDeleteArgs { + string key = 1; +} + +message StorageDeleteReply { + string err = 1; +} + +service Storage { + rpc List(StorageListArgs) returns (StorageListReply); + rpc Get(StorageGetArgs) returns (StorageGetReply); + rpc Put(StoragePutArgs) returns (StoragePutReply); + rpc Delete(StorageDeleteArgs) returns (StorageDeleteReply); +} + +message TTLReply { + int64 TTL = 1; +} + +message SudoPrivilegeArgs { + string path = 1; + string token = 2; +} + +message SudoPrivilegeReply { + bool sudo = 1; +} + +message TaintedReply { + bool tainted = 1; +} + +message CachingDisabledReply { + bool disabled = 1; +} + +message ReplicationStateReply { + int32 state = 1; +} + +message ResponseWrapDataArgs { + bytes data = 1; + int64 TTL = 2; + bool JWT = 3; +} + +message ResponseWrapDataReply { + // WrapInfo info = 1; + string err = 2; +} + +message MlockEnabledReply { + bool enabled = 1; +} + +service SystemView { + rpc DefaultLeaseTTL(Empty) returns (TTLReply); + rpc MaxLeaseTTL(Empty) returns (TTLReply); + rpc SudoPrivilege(SudoPrivilegeArgs) returns (SudoPrivilegeReply); + rpc Tainted(Empty) returns (TaintedReply); + rpc CachingDisabled(Empty) returns (CachingDisabledReply); + rpc ReplicationState(Empty) returns (ReplicationStateReply); + rpc ResponseWrapData(ResponseWrapDataArgs) returns (ResponseWrapDataReply); + rpc MlockEnabled(Empty) returns (MlockEnabledReply); +} + + diff --git a/logical/plugin/pb/translation.go b/logical/plugin/pb/translation.go new file mode 100644 index 000000000000..e17a2293aadf --- /dev/null +++ b/logical/plugin/pb/translation.go @@ -0,0 +1,323 @@ +package pb + +import ( + "encoding/json" + "time" + + "github.com/golang/protobuf/ptypes" + "github.com/hashicorp/vault/logical" +) + +func ErrToString(e error) string { + if e == nil { + return "" + } + + return e.Error() +} + +func LogicalStorageEntryToProtoStorageEntry(e *logical.StorageEntry) *StorageEntry { + return &StorageEntry{ + Key: e.Key, + Value: e.Value, + SealWrap: e.SealWrap, + } +} + +func ProtoStorageEntryToLogicalStorageEntry(e *StorageEntry) *logical.StorageEntry { + return &logical.StorageEntry{ + Key: e.Key, + Value: e.Value, + SealWrap: e.SealWrap, + } +} + +func ProtoLeaseOptionsToLogicalLeaseOptions(l *LeaseOptions) (logical.LeaseOptions, error) { + t, err := ptypes.Timestamp(l.IssueTime) + return logical.LeaseOptions{ + TTL: time.Duration(l.TTL), + Renewable: l.Renewable, + Increment: time.Duration(l.Increment), + IssueTime: t, + }, err +} + +func LogicalLeaseOptionsToProtoLeaseOptions(l logical.LeaseOptions) (*LeaseOptions, error) { + t, err := ptypes.TimestampProto(l.IssueTime) + if err != nil { + return nil, err + } + + return &LeaseOptions{ + TTL: int64(l.TTL), + Renewable: l.Renewable, + Increment: int64(l.Increment), + IssueTime: t, + }, err +} + +func ProtoSecretToLogicalSecret(s *Secret) (*logical.Secret, error) { + if s == nil { + return nil, nil + } + + data := map[string]interface{}{} + err := json.Unmarshal(s.InternalData, &data) + if err != nil { + return nil, err + } + + lease, err := ProtoLeaseOptionsToLogicalLeaseOptions(s.LeaseOptions) + if err != nil { + return nil, err + } + + return &logical.Secret{ + LeaseOptions: lease, + InternalData: data, + LeaseID: s.LeaseId, + }, nil +} + +func LogicalSecretToProtoSecret(s *logical.Secret) (*Secret, error) { + if s == nil { + return nil, nil + } + + buf, err := json.Marshal(s.InternalData) + if err != nil { + return nil, err + } + + lease, err := LogicalLeaseOptionsToProtoLeaseOptions(s.LeaseOptions) + if err != nil { + return nil, err + } + + return &Secret{ + LeaseOptions: lease, + InternalData: buf, + LeaseId: s.LeaseID, + }, err +} + +func LogicalRequestToProtoRequest(r *logical.Request) (*Request, error) { + buf, err := json.Marshal(r.Data) + if err != nil { + return nil, err + } + + secret, err := LogicalSecretToProtoSecret(r.Secret) + if err != nil { + return nil, err + } + + auth, err := LogicalAuthToProtoAuth(r.Auth) + if err != nil { + return nil, err + } + + headers := map[string]*Header{} + for k, v := range r.Headers { + headers[k] = &Header{v} + } + + return &Request{ + Id: r.ID, + ReplicationCluster: r.ReplicationCluster, + Operation: string(r.Operation), + Path: r.Path, + Data: buf, + Secret: secret, + Auth: auth, + Headers: headers, + ClientToken: r.ClientToken, + ClientTokenAccessor: r.ClientTokenAccessor, + DisplayName: r.DisplayName, + MountPoint: r.MountPoint, + MountType: r.MountType, + MountAccessor: r.MountAccessor, + // WrapInfo: args.Request.WrapInfo, + ClientTokenRemainingUses: int64(r.ClientTokenRemainingUses), + //MFACreds: MFACreds, + EntityId: r.EntityID, + PolicyOverride: r.PolicyOverride, + Unauthenticated: r.Unauthenticated, + }, nil +} + +func ProtoRequestToLogicalRequest(r *Request) (*logical.Request, error) { + data := map[string]interface{}{} + err := json.Unmarshal(r.Data, &data) + if err != nil { + return nil, err + } + + secret, err := ProtoSecretToLogicalSecret(r.Secret) + if err != nil { + return nil, err + } + + auth, err := ProtoAuthToLogicalAuth(r.Auth) + if err != nil { + return nil, err + } + + headers := map[string][]string{} + for k, v := range r.Headers { + headers[k] = v.Header + } + + return &logical.Request{ + ID: r.Id, + ReplicationCluster: r.ReplicationCluster, + Operation: logical.Operation(r.Operation), + Path: r.Path, + Data: data, + Secret: secret, + Auth: auth, + Headers: headers, + ClientToken: r.ClientToken, + ClientTokenAccessor: r.ClientTokenAccessor, + DisplayName: r.DisplayName, + MountPoint: r.MountPoint, + MountType: r.MountType, + MountAccessor: r.MountAccessor, + // WrapInfo: args.Request.WrapInfo, + ClientTokenRemainingUses: int(r.ClientTokenRemainingUses), + //MFACreds: MFACreds, + EntityID: r.EntityId, + PolicyOverride: r.PolicyOverride, + Unauthenticated: r.Unauthenticated, + }, nil +} + +func ProtoResponseToLogicalResponse(r *Response) (*logical.Response, error) { + secret, err := ProtoSecretToLogicalSecret(r.Secret) + if err != nil { + return nil, err + } + + auth, err := ProtoAuthToLogicalAuth(r.Auth) + if err != nil { + return nil, err + } + + data := map[string]interface{}{} + err = json.Unmarshal(r.Data, &data) + if err != nil { + return nil, err + } + + return &logical.Response{ + Secret: secret, + Auth: auth, + Data: data, + Redirect: r.Redirect, + Warnings: r.Warnings, + // WrapInfo: r.WrapInfo, + }, nil +} + +func LogicalResponseToProtoResp(r *logical.Response) (*Response, error) { + secret, err := LogicalSecretToProtoSecret(r.Secret) + if err != nil { + return nil, err + } + + auth, err := LogicalAuthToProtoAuth(r.Auth) + if err != nil { + return nil, err + } + + buf, err := json.Marshal(r.Data) + if err != nil { + return nil, err + } + + return &Response{ + Secret: secret, + Auth: auth, + Data: buf, + Redirect: r.Redirect, + Warnings: r.Warnings, + // WrapInfo: r.WrapInfo, + }, nil +} + +func LogicalAliasToProtoAlias(a *logical.Alias) *Alias { + return &Alias{ + MountType: a.MountType, + MountAccessor: a.MountAccessor, + Name: a.Name, + } +} + +func ProtoAliasToLogicalAlias(a *Alias) *logical.Alias { + return &logical.Alias{ + MountType: a.MountType, + MountAccessor: a.MountAccessor, + Name: a.Name, + } +} + +func LogicalAuthToProtoAuth(a *logical.Auth) (*Auth, error) { + if a == nil { + return nil, nil + } + + buf, err := json.Marshal(a.InternalData) + if err != nil { + return nil, err + } + + groupAliases := make([]*Alias, len(a.GroupAliases)) + for i, al := range a.GroupAliases { + groupAliases[i] = LogicalAliasToProtoAlias(al) + } + + return &Auth{ + InternalData: buf, + DisplayName: a.DisplayName, + Policies: a.Policies, + Metadata: a.Metadata, + ClientToken: a.ClientToken, + Accessor: a.Accessor, + Period: int64(a.Period), + NumUses: int64(a.NumUses), + EntityId: a.EntityID, + Alias: LogicalAliasToProtoAlias(a.Alias), + GroupAliases: groupAliases, + }, nil +} + +func ProtoAuthToLogicalAuth(a *Auth) (*logical.Auth, error) { + if a == nil { + return nil, nil + } + + data := map[string]interface{}{} + err := json.Unmarshal(a.InternalData, &data) + if err != nil { + return nil, err + } + + groupAliases := make([]*logical.Alias, len(a.GroupAliases)) + for i, al := range a.GroupAliases { + groupAliases[i] = ProtoAliasToLogicalAlias(al) + } + + return &logical.Auth{ + InternalData: data, + DisplayName: a.DisplayName, + Policies: a.Policies, + Metadata: a.Metadata, + ClientToken: a.ClientToken, + Accessor: a.Accessor, + Period: time.Duration(a.Period), + NumUses: int(a.NumUses), + EntityID: a.EntityId, + Alias: ProtoAliasToLogicalAlias(a.Alias), + GroupAliases: groupAliases, + }, nil +} From 42f3d0684e54067b8e96cb3d54a17859b6c83dad Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Mon, 4 Dec 2017 17:55:54 -0800 Subject: [PATCH 8/9] Serve the GRPC plugin --- logical/plugin/backend.go | 18 ++++++++++++++++++ logical/plugin/grpc_backend_server.go | 9 +++++++++ logical/plugin/plugin.go | 19 ++++++++++++++----- logical/plugin/serve.go | 3 +++ 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/logical/plugin/backend.go b/logical/plugin/backend.go index 081922c9bd3e..2457105db768 100644 --- a/logical/plugin/backend.go +++ b/logical/plugin/backend.go @@ -3,8 +3,11 @@ package plugin import ( "net/rpc" + "google.golang.org/grpc" + "github.com/hashicorp/go-plugin" "github.com/hashicorp/vault/logical" + "github.com/hashicorp/vault/logical/plugin/pb" ) // BackendPlugin is the plugin.Plugin implementation @@ -22,3 +25,18 @@ func (b *BackendPlugin) Server(broker *plugin.MuxBroker) (interface{}, error) { func (b BackendPlugin) Client(broker *plugin.MuxBroker, c *rpc.Client) (interface{}, error) { return &backendPluginClient{client: c, broker: broker, metadataMode: b.metadataMode}, nil } + +func (b BackendPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error { + pb.RegisterBackendServer(s, &backendGRPCPluginServer{ + broker: broker, + factory: b.Factory, + }) + return nil +} + +func (p *BackendPlugin) GRPCClient(broker *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) { + return &backendGRPCPluginClient{ + client: pb.NewBackendClient(c), + broker: broker, + }, nil +} diff --git a/logical/plugin/grpc_backend_server.go b/logical/plugin/grpc_backend_server.go index 2c37ab14fcd9..f2da08a5cf14 100644 --- a/logical/plugin/grpc_backend_server.go +++ b/logical/plugin/grpc_backend_server.go @@ -125,6 +125,15 @@ func (b *backendGRPCPluginServer) Initialize(ctx context.Context, _ *pb.Empty) ( return nil, err } +func (b *backendGRPCPluginServer) InvalidateKey(ctx context.Context, args *pb.InvalidateKeyArgs) (*pb.Empty, error) { + if inMetadataMode() { + return nil, ErrServerInMetadataMode + } + + b.backend.InvalidateKey(args.Key) + return nil, nil +} + func (b *backendGRPCPluginServer) Type(ctx context.Context, _ *pb.Empty) (*pb.TypeReply, error) { return &pb.TypeReply{ Type: uint32(b.backend.Type()), diff --git a/logical/plugin/plugin.go b/logical/plugin/plugin.go index ef8f6d9dedd7..3eaec5706d90 100644 --- a/logical/plugin/plugin.go +++ b/logical/plugin/plugin.go @@ -4,6 +4,7 @@ import ( "crypto/ecdsa" "crypto/rsa" "encoding/gob" + "errors" "fmt" "time" @@ -44,13 +45,13 @@ type BackendPluginClient struct { client *plugin.Client sync.Mutex - *backendPluginClient + logical.Backend } // Cleanup calls the RPC client's Cleanup() func and also calls // the go-plugin's client Kill() func func (b *BackendPluginClient) Cleanup() { - b.backendPluginClient.Cleanup() + b.Backend.Cleanup() b.client.Kill() } @@ -122,13 +123,21 @@ func newPluginClient(sys pluginutil.RunnerUtil, pluginRunner *pluginutil.PluginR return nil, err } + var backend logical.Backend // We should have a logical backend type now. This feels like a normal interface // implementation but is in fact over an RPC connection. - backendRPC := raw.(*backendPluginClient) + switch raw.(type) { + case *backendPluginClient: + backend = raw.(*backendPluginClient) + case *backendGRPCPluginClient: + backend = raw.(*backendGRPCPluginClient) + default: + return nil, errors.New("Unsupported plugin client type") + } return &BackendPluginClient{ - client: client, - backendPluginClient: backendRPC, + client: client, + Backend: backend, }, nil } diff --git a/logical/plugin/serve.go b/logical/plugin/serve.go index 279f6d8ac15d..b25e7c60756e 100644 --- a/logical/plugin/serve.go +++ b/logical/plugin/serve.go @@ -40,6 +40,9 @@ func Serve(opts *ServeOpts) error { HandshakeConfig: handshakeConfig, Plugins: pluginMap, TLSProvider: opts.TLSProviderFunc, + + // A non-nil value here enables gRPC serving for this plugin... + GRPCServer: plugin.DefaultGRPCServer, }) return nil From 99ebb3f264695b875e07a53f417cdb38acdbb46f Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Tue, 5 Dec 2017 11:50:25 -0800 Subject: [PATCH 9/9] Add backwards compatibility to the database plugins --- builtin/logical/database/dbplugin/client.go | 104 +++--------------- .../logical/database/dbplugin/grpc_client.go | 88 +++++++++++++++ .../logical/database/dbplugin/grpc_server.go | 70 ++++++++++++ .../database/dbplugin/netrpc_client.go | 75 +++++++++++++ .../database/dbplugin/netrpc_server.go | 74 +++++++++++++ builtin/logical/database/dbplugin/plugin.go | 16 ++- builtin/logical/database/dbplugin/server.go | 65 ----------- 7 files changed, 335 insertions(+), 157 deletions(-) create mode 100644 builtin/logical/database/dbplugin/grpc_client.go create mode 100644 builtin/logical/database/dbplugin/grpc_server.go create mode 100644 builtin/logical/database/dbplugin/netrpc_client.go create mode 100644 builtin/logical/database/dbplugin/netrpc_server.go diff --git a/builtin/logical/database/dbplugin/client.go b/builtin/logical/database/dbplugin/client.go index 462d4af717f6..e5eff0c1a277 100644 --- a/builtin/logical/database/dbplugin/client.go +++ b/builtin/logical/database/dbplugin/client.go @@ -1,14 +1,10 @@ package dbplugin import ( - "context" - "encoding/json" + "errors" + "fmt" "sync" - "time" - "google.golang.org/grpc" - - "github.com/golang/protobuf/ptypes" "github.com/hashicorp/go-plugin" "github.com/hashicorp/vault/helper/pluginutil" log "github.com/mgutz/logxi/v1" @@ -20,11 +16,11 @@ type DatabasePluginClient struct { client *plugin.Client sync.Mutex - *gRPCClient + Database } func (dc *DatabasePluginClient) Close() error { - err := dc.gRPCClient.Close() + err := dc.Database.Close() dc.client.Kill() return err @@ -58,88 +54,20 @@ func newPluginClient(sys pluginutil.RunnerUtil, pluginRunner *pluginutil.PluginR // We should have a database type now. This feels like a normal interface // implementation but is in fact over an RPC connection. - databaseRPC := raw.(*gRPCClient) + var db Database + switch raw.(type) { + case *gRPCClient: + db = raw.(*gRPCClient) + case *databasePluginRPCClient: + logger.Warn(fmt.Sprintf("Plugin '%s' is using deprecated net RPC transport. Recompile plugin to upgrade to gRPC.", pluginRunner.Name)) + db = raw.(*databasePluginRPCClient) + default: + return nil, errors.New("unsupported client type") + } // Wrap RPC implimentation in DatabasePluginClient return &DatabasePluginClient{ - client: client, - gRPCClient: databaseRPC, + client: client, + Database: db, }, nil } - -// ---- gRPC client domain ---- - -type gRPCClient struct { - client DatabaseClient - clientConn *grpc.ClientConn -} - -func (c gRPCClient) Type() (string, error) { - resp, err := c.client.Type(context.Background(), &Empty{}, grpc.FailFast(true)) - if err != nil { - return "", err - } - - return resp.Type, err -} - -func (c gRPCClient) CreateUser(ctx context.Context, statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error) { - t, err := ptypes.TimestampProto(expiration) - if err != nil { - return "", "", err - } - - resp, err := c.client.CreateUser(ctx, &CreateUserRequest{ - Statements: &statements, - UsernameConfig: &usernameConfig, - Expiration: t, - }, grpc.FailFast(true)) - if err != nil { - return "", "", err - } - - return resp.Username, resp.Password, err -} - -func (c *gRPCClient) RenewUser(ctx context.Context, statements Statements, username string, expiration time.Time) error { - t, err := ptypes.TimestampProto(expiration) - if err != nil { - return err - } - - _, err = c.client.RenewUser(ctx, &RenewUserRequest{ - Statements: &statements, - Username: username, - Expiration: t, - }, grpc.FailFast(true)) - - return err -} - -func (c *gRPCClient) RevokeUser(ctx context.Context, statements Statements, username string) error { - _, err := c.client.RevokeUser(ctx, &RevokeUserRequest{ - Statements: &statements, - Username: username, - }, grpc.FailFast(true)) - - return err -} - -func (c *gRPCClient) Initialize(ctx context.Context, config map[string]interface{}, verifyConnection bool) error { - configRaw, err := json.Marshal(config) - if err != nil { - return err - } - - _, err = c.client.Initialize(ctx, &InitializeRequest{ - Config: configRaw, - VerifyConnection: verifyConnection, - }, grpc.FailFast(true)) - - return err -} - -func (c *gRPCClient) Close() error { - _, err := c.client.Close(context.Background(), &Empty{}, grpc.FailFast(true)) - return err -} diff --git a/builtin/logical/database/dbplugin/grpc_client.go b/builtin/logical/database/dbplugin/grpc_client.go new file mode 100644 index 000000000000..5c67538aafe2 --- /dev/null +++ b/builtin/logical/database/dbplugin/grpc_client.go @@ -0,0 +1,88 @@ +package dbplugin + +import ( + "context" + "encoding/json" + "time" + + "google.golang.org/grpc" + + "github.com/golang/protobuf/ptypes" +) + +// ---- gRPC client domain ---- + +type gRPCClient struct { + client DatabaseClient + clientConn *grpc.ClientConn +} + +func (c gRPCClient) Type() (string, error) { + resp, err := c.client.Type(context.Background(), &Empty{}, grpc.FailFast(true)) + if err != nil { + return "", err + } + + return resp.Type, err +} + +func (c gRPCClient) CreateUser(ctx context.Context, statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error) { + t, err := ptypes.TimestampProto(expiration) + if err != nil { + return "", "", err + } + + resp, err := c.client.CreateUser(ctx, &CreateUserRequest{ + Statements: &statements, + UsernameConfig: &usernameConfig, + Expiration: t, + }, grpc.FailFast(true)) + if err != nil { + return "", "", err + } + + return resp.Username, resp.Password, err +} + +func (c *gRPCClient) RenewUser(ctx context.Context, statements Statements, username string, expiration time.Time) error { + t, err := ptypes.TimestampProto(expiration) + if err != nil { + return err + } + + _, err = c.client.RenewUser(ctx, &RenewUserRequest{ + Statements: &statements, + Username: username, + Expiration: t, + }, grpc.FailFast(true)) + + return err +} + +func (c *gRPCClient) RevokeUser(ctx context.Context, statements Statements, username string) error { + _, err := c.client.RevokeUser(ctx, &RevokeUserRequest{ + Statements: &statements, + Username: username, + }, grpc.FailFast(true)) + + return err +} + +func (c *gRPCClient) Initialize(ctx context.Context, config map[string]interface{}, verifyConnection bool) error { + configRaw, err := json.Marshal(config) + if err != nil { + return err + } + + _, err = c.client.Initialize(ctx, &InitializeRequest{ + Config: configRaw, + VerifyConnection: verifyConnection, + }, grpc.FailFast(true)) + + return err +} + +func (c *gRPCClient) Close() error { + _, err := c.client.Close(context.Background(), &Empty{}, grpc.FailFast(true)) + return err +} diff --git a/builtin/logical/database/dbplugin/grpc_server.go b/builtin/logical/database/dbplugin/grpc_server.go new file mode 100644 index 000000000000..fd64f402eaac --- /dev/null +++ b/builtin/logical/database/dbplugin/grpc_server.go @@ -0,0 +1,70 @@ +package dbplugin + +import ( + "context" + "encoding/json" + + "github.com/golang/protobuf/ptypes" +) + +// ---- gRPC Server domain ---- + +type gRPCServer struct { + impl Database +} + +func (s *gRPCServer) Type(context.Context, *Empty) (*TypeResponse, error) { + t, err := s.impl.Type() + if err != nil { + return nil, err + } + + return &TypeResponse{ + Type: t, + }, nil +} + +func (s *gRPCServer) CreateUser(ctx context.Context, req *CreateUserRequest) (*CreateUserResponse, error) { + e, err := ptypes.Timestamp(req.Expiration) + if err != nil { + return nil, err + } + + u, p, err := s.impl.CreateUser(ctx, *req.Statements, *req.UsernameConfig, e) + + return &CreateUserResponse{ + Username: u, + Password: p, + }, err +} + +func (s *gRPCServer) RenewUser(ctx context.Context, req *RenewUserRequest) (*Empty, error) { + e, err := ptypes.Timestamp(req.Expiration) + if err != nil { + return nil, err + } + err = s.impl.RenewUser(ctx, *req.Statements, req.Username, e) + return &Empty{}, err +} + +func (s *gRPCServer) RevokeUser(ctx context.Context, req *RevokeUserRequest) (*Empty, error) { + err := s.impl.RevokeUser(ctx, *req.Statements, req.Username) + return &Empty{}, err +} + +func (s *gRPCServer) Initialize(ctx context.Context, req *InitializeRequest) (*Empty, error) { + config := map[string]interface{}{} + + err := json.Unmarshal(req.Config, &config) + if err != nil { + return nil, err + } + + err = s.impl.Initialize(ctx, config, req.VerifyConnection) + return &Empty{}, err +} + +func (s *gRPCServer) Close(_ context.Context, _ *Empty) (*Empty, error) { + s.impl.Close() + return &Empty{}, nil +} diff --git a/builtin/logical/database/dbplugin/netrpc_client.go b/builtin/logical/database/dbplugin/netrpc_client.go new file mode 100644 index 000000000000..ad9a44b0e600 --- /dev/null +++ b/builtin/logical/database/dbplugin/netrpc_client.go @@ -0,0 +1,75 @@ +package dbplugin + +import ( + "context" + "fmt" + "net/rpc" + "time" +) + +// ---- RPC client domain ---- +// databasePluginRPCClient implements Database and is used on the client to +// make RPC calls to a plugin. +type databasePluginRPCClient struct { + client *rpc.Client +} + +func (dr *databasePluginRPCClient) Type() (string, error) { + var dbType string + err := dr.client.Call("Plugin.Type", struct{}{}, &dbType) + + return fmt.Sprintf("plugin-%s", dbType), err +} + +func (dr *databasePluginRPCClient) CreateUser(_ context.Context, statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error) { + req := CreateUserRequestRPC{ + Statements: statements, + UsernameConfig: usernameConfig, + Expiration: expiration, + } + + var resp CreateUserResponse + err = dr.client.Call("Plugin.CreateUser", req, &resp) + + return resp.Username, resp.Password, err +} + +func (dr *databasePluginRPCClient) RenewUser(_ context.Context, statements Statements, username string, expiration time.Time) error { + req := RenewUserRequestRPC{ + Statements: statements, + Username: username, + Expiration: expiration, + } + + err := dr.client.Call("Plugin.RenewUser", req, &struct{}{}) + + return err +} + +func (dr *databasePluginRPCClient) RevokeUser(_ context.Context, statements Statements, username string) error { + req := RevokeUserRequestRPC{ + Statements: statements, + Username: username, + } + + err := dr.client.Call("Plugin.RevokeUser", req, &struct{}{}) + + return err +} + +func (dr *databasePluginRPCClient) Initialize(_ context.Context, conf map[string]interface{}, verifyConnection bool) error { + req := InitializeRequestRPC{ + Config: conf, + VerifyConnection: verifyConnection, + } + + err := dr.client.Call("Plugin.Initialize", req, &struct{}{}) + + return err +} + +func (dr *databasePluginRPCClient) Close() error { + err := dr.client.Call("Plugin.Close", struct{}{}, &struct{}{}) + + return err +} diff --git a/builtin/logical/database/dbplugin/netrpc_server.go b/builtin/logical/database/dbplugin/netrpc_server.go new file mode 100644 index 000000000000..0bebf0056426 --- /dev/null +++ b/builtin/logical/database/dbplugin/netrpc_server.go @@ -0,0 +1,74 @@ +package dbplugin + +import ( + "context" + "time" +) + +// ---- RPC server domain ---- + +// databasePluginRPCServer implements an RPC version of Database and is run +// inside a plugin. It wraps an underlying implementation of Database. +type databasePluginRPCServer struct { + impl Database +} + +func (ds *databasePluginRPCServer) Type(_ struct{}, resp *string) error { + var err error + *resp, err = ds.impl.Type() + return err +} + +func (ds *databasePluginRPCServer) CreateUser(args *CreateUserRequestRPC, resp *CreateUserResponse) error { + var err error + resp.Username, resp.Password, err = ds.impl.CreateUser(context.Background(), args.Statements, args.UsernameConfig, args.Expiration) + + return err +} + +func (ds *databasePluginRPCServer) RenewUser(args *RenewUserRequestRPC, _ *struct{}) error { + err := ds.impl.RenewUser(context.Background(), args.Statements, args.Username, args.Expiration) + + return err +} + +func (ds *databasePluginRPCServer) RevokeUser(args *RevokeUserRequestRPC, _ *struct{}) error { + err := ds.impl.RevokeUser(context.Background(), args.Statements, args.Username) + + return err +} + +func (ds *databasePluginRPCServer) Initialize(args *InitializeRequestRPC, _ *struct{}) error { + err := ds.impl.Initialize(context.Background(), args.Config, args.VerifyConnection) + + return err +} + +func (ds *databasePluginRPCServer) Close(_ struct{}, _ *struct{}) error { + ds.impl.Close() + return nil +} + +// ---- RPC Request Args Domain ---- + +type InitializeRequestRPC struct { + Config map[string]interface{} + VerifyConnection bool +} + +type CreateUserRequestRPC struct { + Statements Statements + UsernameConfig UsernameConfig + Expiration time.Time +} + +type RenewUserRequestRPC struct { + Statements Statements + Username string + Expiration time.Time +} + +type RevokeUserRequestRPC struct { + Statements Statements + Username string +} diff --git a/builtin/logical/database/dbplugin/plugin.go b/builtin/logical/database/dbplugin/plugin.go index 53590f408289..2ad4f2d0c532 100644 --- a/builtin/logical/database/dbplugin/plugin.go +++ b/builtin/logical/database/dbplugin/plugin.go @@ -3,6 +3,7 @@ package dbplugin import ( "context" "fmt" + "net/rpc" "time" "google.golang.org/grpc" @@ -83,7 +84,7 @@ func PluginFactory(pluginName string, sys pluginutil.LookRunnerUtil, logger log. // 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{ - ProtocolVersion: 4, + ProtocolVersion: 3, MagicCookieKey: "VAULT_DATABASE_PLUGIN", MagicCookieValue: "926a0820-aea2-be28-51d6-83cdf00e8edb", } @@ -91,16 +92,23 @@ var handshakeConfig = plugin.HandshakeConfig{ // DatabasePlugin implements go-plugin's Plugin interface. It has methods for // retrieving a server and a client instance of the plugin. type DatabasePlugin struct { - plugin.NetRPCUnsupportedPlugin impl Database } -func (d DatabasePlugin) GRPCServer(s *grpc.Server) error { +func (d DatabasePlugin) Server(*plugin.MuxBroker) (interface{}, error) { + return &databasePluginRPCServer{impl: d.impl}, nil +} + +func (DatabasePlugin) Client(b *plugin.MuxBroker, c *rpc.Client) (interface{}, error) { + return &databasePluginRPCClient{client: c}, nil +} + +func (d DatabasePlugin) GRPCServer(_ *plugin.GRPCBroker, s *grpc.Server) error { RegisterDatabaseServer(s, &gRPCServer{impl: d.impl}) return nil } -func (DatabasePlugin) GRPCClient(c *grpc.ClientConn) (interface{}, error) { +func (DatabasePlugin) GRPCClient(_ *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) { return &gRPCClient{ client: NewDatabaseClient(c), clientConn: c, diff --git a/builtin/logical/database/dbplugin/server.go b/builtin/logical/database/dbplugin/server.go index 471b9a3866fb..2dc8f3aa08e3 100644 --- a/builtin/logical/database/dbplugin/server.go +++ b/builtin/logical/database/dbplugin/server.go @@ -1,11 +1,8 @@ package dbplugin import ( - "context" "crypto/tls" - "encoding/json" - "github.com/golang/protobuf/ptypes" "github.com/hashicorp/go-plugin" ) @@ -29,65 +26,3 @@ func Serve(db Database, tlsProvider func() (*tls.Config, error)) { GRPCServer: plugin.DefaultGRPCServer, }) } - -// ---- gRPC Server domain ---- - -type gRPCServer struct { - impl Database -} - -func (s *gRPCServer) Type(context.Context, *Empty) (*TypeResponse, error) { - t, err := s.impl.Type() - if err != nil { - return nil, err - } - - return &TypeResponse{ - Type: t, - }, nil -} - -func (s *gRPCServer) CreateUser(ctx context.Context, req *CreateUserRequest) (*CreateUserResponse, error) { - e, err := ptypes.Timestamp(req.Expiration) - if err != nil { - return nil, err - } - - u, p, err := s.impl.CreateUser(ctx, *req.Statements, *req.UsernameConfig, e) - - return &CreateUserResponse{ - Username: u, - Password: p, - }, err -} - -func (s *gRPCServer) RenewUser(ctx context.Context, req *RenewUserRequest) (*Empty, error) { - e, err := ptypes.Timestamp(req.Expiration) - if err != nil { - return nil, err - } - err = s.impl.RenewUser(ctx, *req.Statements, req.Username, e) - return &Empty{}, err -} - -func (s *gRPCServer) RevokeUser(ctx context.Context, req *RevokeUserRequest) (*Empty, error) { - err := s.impl.RevokeUser(ctx, *req.Statements, req.Username) - return &Empty{}, err -} - -func (s *gRPCServer) Initialize(ctx context.Context, req *InitializeRequest) (*Empty, error) { - config := map[string]interface{}{} - - err := json.Unmarshal(req.Config, &config) - if err != nil { - return nil, err - } - - err = s.impl.Initialize(ctx, config, req.VerifyConnection) - return &Empty{}, err -} - -func (s *gRPCServer) Close(_ context.Context, _ *Empty) (*Empty, error) { - s.impl.Close() - return &Empty{}, nil -}