Update to api 1.0.1 and sdk 0.1.8

This commit is contained in:
Jeff Mitchell 2019-04-15 14:10:07 -04:00
parent 4dd880871e
commit 213b9fd1cf
94 changed files with 153 additions and 2802 deletions

View File

@ -154,7 +154,7 @@ proto:
protoc sdk/physical/types.proto --go_out=plugins=grpc,paths=source_relative:. protoc sdk/physical/types.proto --go_out=plugins=grpc,paths=source_relative:.
protoc helper/identity/mfa/types.proto --go_out=plugins=grpc,paths=source_relative:. protoc helper/identity/mfa/types.proto --go_out=plugins=grpc,paths=source_relative:.
protoc helper/identity/types.proto --go_out=plugins=grpc,paths=source_relative:. protoc helper/identity/types.proto --go_out=plugins=grpc,paths=source_relative:.
protoc builtin/logical/database/dbplugin/*.proto --go_out=plugins=grpc,paths=source_relative:. protoc sdk/database/dbplugin/*.proto --go_out=plugins=grpc,paths=source_relative:.
protoc sdk/plugin/pb/*.proto --go_out=plugins=grpc,paths=source_relative:. protoc sdk/plugin/pb/*.proto --go_out=plugins=grpc,paths=source_relative:.
sed -i -e 's/Idp/IDP/' -e 's/Url/URL/' -e 's/Id/ID/' -e 's/IDentity/Identity/' -e 's/EntityId/EntityID/' -e 's/Api/API/' -e 's/Qr/QR/' -e 's/Totp/TOTP/' -e 's/Mfa/MFA/' -e 's/Pingid/PingID/' -e 's/protobuf:"/sentinel:"" protobuf:"/' -e 's/namespaceId/namespaceID/' -e 's/Ttl/TTL/' -e 's/BoundCidrs/BoundCIDRs/' helper/identity/types.pb.go helper/identity/mfa/types.pb.go helper/storagepacker/types.pb.go sdk/plugin/pb/backend.pb.go sdk/logical/identity.pb.go sed -i -e 's/Idp/IDP/' -e 's/Url/URL/' -e 's/Id/ID/' -e 's/IDentity/Identity/' -e 's/EntityId/EntityID/' -e 's/Api/API/' -e 's/Qr/QR/' -e 's/Totp/TOTP/' -e 's/Mfa/MFA/' -e 's/Pingid/PingID/' -e 's/protobuf:"/sentinel:"" protobuf:"/' -e 's/namespaceId/namespaceID/' -e 's/Ttl/TTL/' -e 's/BoundCidrs/BoundCIDRs/' helper/identity/types.pb.go helper/identity/mfa/types.pb.go helper/storagepacker/types.pb.go sdk/plugin/pb/backend.pb.go sdk/logical/identity.pb.go
sed -i -e 's/Iv/IV/' -e 's/Hmac/HMAC/' sdk/physical/types.pb.go sed -i -e 's/Iv/IV/' -e 's/Hmac/HMAC/' sdk/physical/types.pb.go

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -11,8 +11,8 @@ import (
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
uuid "github.com/hashicorp/go-uuid" uuid "github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/plugins/helper/database/dbutil" "github.com/hashicorp/vault/sdk/database/helper/dbutil"
"github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/helper/strutil"
"github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/sdk/logical"

View File

@ -14,11 +14,11 @@ import (
"github.com/go-test/deep" "github.com/go-test/deep"
"github.com/hashicorp/vault/api" "github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
"github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/helper/namespace"
vaulthttp "github.com/hashicorp/vault/http" vaulthttp "github.com/hashicorp/vault/http"
"github.com/hashicorp/vault/plugins/database/postgresql" "github.com/hashicorp/vault/plugins/database/postgresql"
"github.com/hashicorp/vault/plugins/helper/database/dbutil" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/sdk/database/helper/dbutil"
"github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/consts" "github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/helper/pluginutil" "github.com/hashicorp/vault/sdk/helper/pluginutil"
@ -120,7 +120,7 @@ func TestBackend_PluginMain(t *testing.T) {
args := []string{"--ca-cert=" + caPEM} args := []string{"--ca-cert=" + caPEM}
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(args) flags.Parse(args)

View File

@ -1,89 +0,0 @@
package dbplugin
import (
"context"
"errors"
"sync"
log "github.com/hashicorp/go-hclog"
plugin "github.com/hashicorp/go-plugin"
"github.com/hashicorp/vault/sdk/helper/pluginutil"
)
// DatabasePluginClient embeds a databasePluginRPCClient and wraps it's Close
// method to also call Kill() on the plugin.Client.
type DatabasePluginClient struct {
client *plugin.Client
sync.Mutex
Database
}
// This wraps the Close call and ensures we both close the database connection
// and kill the plugin.
func (dc *DatabasePluginClient) Close() error {
err := dc.Database.Close()
dc.client.Kill()
return err
}
// NewPluginClient returns a databaseRPCClient with a connection to a running
// plugin. The client is wrapped in a DatabasePluginClient object to ensure the
// plugin is killed on call of Close().
func NewPluginClient(ctx context.Context, sys pluginutil.RunnerUtil, pluginRunner *pluginutil.PluginRunner, logger log.Logger, isMetadataMode bool) (Database, error) {
// pluginSets is the map of plugins we can dispense.
pluginSets := map[int]plugin.PluginSet{
// Version 3 used to supports both protocols. We want to keep it around
// since it's possible old plugins built against this version will still
// work with gRPC. There is currently no difference between version 3
// and version 4.
3: plugin.PluginSet{
"database": new(GRPCDatabasePlugin),
},
// Version 4 only supports gRPC
4: plugin.PluginSet{
"database": new(GRPCDatabasePlugin),
},
}
var client *plugin.Client
var err error
if isMetadataMode {
client, err = pluginRunner.RunMetadataMode(ctx, sys, pluginSets, handshakeConfig, []string{}, logger)
} else {
client, err = pluginRunner.Run(ctx, sys, pluginSets, handshakeConfig, []string{}, logger)
}
if err != nil {
return nil, err
}
// Connect via RPC
rpcClient, err := client.Client()
if err != nil {
return nil, err
}
// Request the plugin
raw, err := rpcClient.Dispense("database")
if err != nil {
return nil, err
}
// We should have a database type now. This feels like a normal interface
// implementation but is in fact over an RPC connection.
var db Database
switch raw.(type) {
case *gRPCClient:
db = raw.(*gRPCClient)
default:
return nil, errors.New("unsupported client type")
}
// Wrap RPC implementation in DatabasePluginClient
return &DatabasePluginClient{
client: client,
Database: db,
}, nil
}

File diff suppressed because it is too large Load Diff

View File

@ -1,93 +0,0 @@
syntax = "proto3";
option go_package = "github.com/hashicorp/vault/builtin/logical/database/dbplugin";
package dbplugin;
import "google/protobuf/timestamp.proto";
message InitializeRequest {
option deprecated = true;
bytes config = 1;
bool verify_connection = 2;
}
message InitRequest {
bytes 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 RotateRootCredentialsRequest {
repeated string statements = 1;
}
message Statements {
// DEPRECATED, will be removed in 0.12
string creation_statements = 1 [deprecated=true];
// DEPRECATED, will be removed in 0.12
string revocation_statements = 2 [deprecated=true];
// DEPRECATED, will be removed in 0.12
string rollback_statements = 3 [deprecated=true];
// DEPRECATED, will be removed in 0.12
string renew_statements = 4 [deprecated=true];
repeated string creation = 5;
repeated string revocation = 6;
repeated string rollback = 7;
repeated string renewal = 8;
}
message UsernameConfig {
string DisplayName = 1;
string RoleName = 2;
}
message InitResponse {
bytes config = 1;
}
message CreateUserResponse {
string username = 1;
string password = 2;
}
message TypeResponse {
string type = 1;
}
message RotateRootCredentialsResponse {
bytes config = 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 RotateRootCredentials(RotateRootCredentialsRequest) returns (RotateRootCredentialsResponse);
rpc Init(InitRequest) returns (InitResponse);
rpc Close(Empty) returns (Empty);
rpc Initialize(InitializeRequest) returns (Empty) {
option deprecated = true;
};
}

View File

@ -1,275 +0,0 @@
package dbplugin
import (
"context"
"errors"
"net/url"
"strings"
"sync"
"time"
"github.com/hashicorp/errwrap"
metrics "github.com/armon/go-metrics"
log "github.com/hashicorp/go-hclog"
)
// ---- Tracing Middleware Domain ----
// databaseTracingMiddleware wraps a implementation of Database and executes
// trace logging on function call.
type databaseTracingMiddleware struct {
next Database
logger log.Logger
}
func (mw *databaseTracingMiddleware) Type() (string, error) {
return mw.next.Type()
}
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("create user", "status", "finished", "err", err, "took", time.Since(then))
}(time.Now())
mw.logger.Trace("create user", "status", "started")
return mw.next.CreateUser(ctx, statements, usernameConfig, expiration)
}
func (mw *databaseTracingMiddleware) RenewUser(ctx context.Context, statements Statements, username string, expiration time.Time) (err error) {
defer func(then time.Time) {
mw.logger.Trace("renew user", "status", "finished", "err", err, "took", time.Since(then))
}(time.Now())
mw.logger.Trace("renew user", "status", "started")
return mw.next.RenewUser(ctx, statements, username, expiration)
}
func (mw *databaseTracingMiddleware) RevokeUser(ctx context.Context, statements Statements, username string) (err error) {
defer func(then time.Time) {
mw.logger.Trace("revoke user", "status", "finished", "err", err, "took", time.Since(then))
}(time.Now())
mw.logger.Trace("revoke user", "status", "started")
return mw.next.RevokeUser(ctx, statements, username)
}
func (mw *databaseTracingMiddleware) RotateRootCredentials(ctx context.Context, statements []string) (conf map[string]interface{}, err error) {
defer func(then time.Time) {
mw.logger.Trace("rotate root credentials", "status", "finished", "err", err, "took", time.Since(then))
}(time.Now())
mw.logger.Trace("rotate root credentials", "status", "started")
return mw.next.RotateRootCredentials(ctx, statements)
}
func (mw *databaseTracingMiddleware) Initialize(ctx context.Context, conf map[string]interface{}, verifyConnection bool) error {
_, err := mw.Init(ctx, conf, verifyConnection)
return err
}
func (mw *databaseTracingMiddleware) Init(ctx context.Context, conf map[string]interface{}, verifyConnection bool) (saveConf map[string]interface{}, err error) {
defer func(then time.Time) {
mw.logger.Trace("initialize", "status", "finished", "verify", verifyConnection, "err", err, "took", time.Since(then))
}(time.Now())
mw.logger.Trace("initialize", "status", "started")
return mw.next.Init(ctx, conf, verifyConnection)
}
func (mw *databaseTracingMiddleware) Close() (err error) {
defer func(then time.Time) {
mw.logger.Trace("close", "status", "finished", "err", err, "took", time.Since(then))
}(time.Now())
mw.logger.Trace("close", "status", "started")
return mw.next.Close()
}
// ---- Metrics Middleware Domain ----
// databaseMetricsMiddleware wraps an implementation of Databases and on
// function call logs metrics about this instance.
type databaseMetricsMiddleware struct {
next Database
typeStr string
}
func (mw *databaseMetricsMiddleware) Type() (string, error) {
return mw.next.Type()
}
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)
if err != nil {
metrics.IncrCounter([]string{"database", "CreateUser", "error"}, 1)
metrics.IncrCounter([]string{"database", mw.typeStr, "CreateUser", "error"}, 1)
}
}(time.Now())
metrics.IncrCounter([]string{"database", "CreateUser"}, 1)
metrics.IncrCounter([]string{"database", mw.typeStr, "CreateUser"}, 1)
return mw.next.CreateUser(ctx, statements, usernameConfig, expiration)
}
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)
if err != nil {
metrics.IncrCounter([]string{"database", "RenewUser", "error"}, 1)
metrics.IncrCounter([]string{"database", mw.typeStr, "RenewUser", "error"}, 1)
}
}(time.Now())
metrics.IncrCounter([]string{"database", "RenewUser"}, 1)
metrics.IncrCounter([]string{"database", mw.typeStr, "RenewUser"}, 1)
return mw.next.RenewUser(ctx, statements, username, expiration)
}
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)
if err != nil {
metrics.IncrCounter([]string{"database", "RevokeUser", "error"}, 1)
metrics.IncrCounter([]string{"database", mw.typeStr, "RevokeUser", "error"}, 1)
}
}(time.Now())
metrics.IncrCounter([]string{"database", "RevokeUser"}, 1)
metrics.IncrCounter([]string{"database", mw.typeStr, "RevokeUser"}, 1)
return mw.next.RevokeUser(ctx, statements, username)
}
func (mw *databaseMetricsMiddleware) RotateRootCredentials(ctx context.Context, statements []string) (conf map[string]interface{}, err error) {
defer func(now time.Time) {
metrics.MeasureSince([]string{"database", "RotateRootCredentials"}, now)
metrics.MeasureSince([]string{"database", mw.typeStr, "RotateRootCredentials"}, now)
if err != nil {
metrics.IncrCounter([]string{"database", "RotateRootCredentials", "error"}, 1)
metrics.IncrCounter([]string{"database", mw.typeStr, "RotateRootCredentials", "error"}, 1)
}
}(time.Now())
metrics.IncrCounter([]string{"database", "RotateRootCredentials"}, 1)
metrics.IncrCounter([]string{"database", mw.typeStr, "RotateRootCredentials"}, 1)
return mw.next.RotateRootCredentials(ctx, statements)
}
func (mw *databaseMetricsMiddleware) Initialize(ctx context.Context, conf map[string]interface{}, verifyConnection bool) error {
_, err := mw.Init(ctx, conf, verifyConnection)
return err
}
func (mw *databaseMetricsMiddleware) Init(ctx context.Context, conf map[string]interface{}, verifyConnection bool) (saveConf map[string]interface{}, err error) {
defer func(now time.Time) {
metrics.MeasureSince([]string{"database", "Initialize"}, now)
metrics.MeasureSince([]string{"database", mw.typeStr, "Initialize"}, now)
if err != nil {
metrics.IncrCounter([]string{"database", "Initialize", "error"}, 1)
metrics.IncrCounter([]string{"database", mw.typeStr, "Initialize", "error"}, 1)
}
}(time.Now())
metrics.IncrCounter([]string{"database", "Initialize"}, 1)
metrics.IncrCounter([]string{"database", mw.typeStr, "Initialize"}, 1)
return mw.next.Init(ctx, conf, verifyConnection)
}
func (mw *databaseMetricsMiddleware) Close() (err error) {
defer func(now time.Time) {
metrics.MeasureSince([]string{"database", "Close"}, now)
metrics.MeasureSince([]string{"database", mw.typeStr, "Close"}, now)
if err != nil {
metrics.IncrCounter([]string{"database", "Close", "error"}, 1)
metrics.IncrCounter([]string{"database", mw.typeStr, "Close", "error"}, 1)
}
}(time.Now())
metrics.IncrCounter([]string{"database", "Close"}, 1)
metrics.IncrCounter([]string{"database", mw.typeStr, "Close"}, 1)
return mw.next.Close()
}
// ---- Error Sanitizer Middleware Domain ----
// DatabaseErrorSanitizerMiddleware wraps an implementation of Databases and
// sanitizes returned error messages
type DatabaseErrorSanitizerMiddleware struct {
l sync.RWMutex
next Database
secretsFn func() map[string]interface{}
}
func NewDatabaseErrorSanitizerMiddleware(next Database, secretsFn func() map[string]interface{}) *DatabaseErrorSanitizerMiddleware {
return &DatabaseErrorSanitizerMiddleware{
next: next,
secretsFn: secretsFn,
}
}
func (mw *DatabaseErrorSanitizerMiddleware) Type() (string, error) {
dbType, err := mw.next.Type()
return dbType, mw.sanitize(err)
}
func (mw *DatabaseErrorSanitizerMiddleware) CreateUser(ctx context.Context, statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error) {
username, password, err = mw.next.CreateUser(ctx, statements, usernameConfig, expiration)
return username, password, mw.sanitize(err)
}
func (mw *DatabaseErrorSanitizerMiddleware) RenewUser(ctx context.Context, statements Statements, username string, expiration time.Time) (err error) {
return mw.sanitize(mw.next.RenewUser(ctx, statements, username, expiration))
}
func (mw *DatabaseErrorSanitizerMiddleware) RevokeUser(ctx context.Context, statements Statements, username string) (err error) {
return mw.sanitize(mw.next.RevokeUser(ctx, statements, username))
}
func (mw *DatabaseErrorSanitizerMiddleware) RotateRootCredentials(ctx context.Context, statements []string) (conf map[string]interface{}, err error) {
conf, err = mw.next.RotateRootCredentials(ctx, statements)
return conf, mw.sanitize(err)
}
func (mw *DatabaseErrorSanitizerMiddleware) Initialize(ctx context.Context, conf map[string]interface{}, verifyConnection bool) error {
_, err := mw.Init(ctx, conf, verifyConnection)
return err
}
func (mw *DatabaseErrorSanitizerMiddleware) Init(ctx context.Context, conf map[string]interface{}, verifyConnection bool) (saveConf map[string]interface{}, err error) {
saveConf, err = mw.next.Init(ctx, conf, verifyConnection)
return saveConf, mw.sanitize(err)
}
func (mw *DatabaseErrorSanitizerMiddleware) Close() (err error) {
return mw.sanitize(mw.next.Close())
}
// sanitize
func (mw *DatabaseErrorSanitizerMiddleware) sanitize(err error) error {
if err == nil {
return nil
}
if errwrap.ContainsType(err, new(url.Error)) {
return errors.New("unable to parse connection url")
}
if mw.secretsFn != nil {
for k, v := range mw.secretsFn() {
if k == "" {
continue
}
err = errors.New(strings.Replace(err.Error(), k, v.(string), -1))
}
}
return err
}

View File

@ -1,285 +0,0 @@
package dbplugin
import (
"context"
"encoding/json"
"errors"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/golang/protobuf/ptypes"
"github.com/hashicorp/vault/sdk/helper/pluginutil"
)
var (
ErrPluginShutdown = errors.New("plugin shutdown")
)
// ---- 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) RotateRootCredentials(ctx context.Context, req *RotateRootCredentialsRequest) (*RotateRootCredentialsResponse, error) {
resp, err := s.impl.RotateRootCredentials(ctx, req.Statements)
if err != nil {
return nil, err
}
respConfig, err := json.Marshal(resp)
if err != nil {
return nil, err
}
return &RotateRootCredentialsResponse{
Config: respConfig,
}, err
}
func (s *gRPCServer) Initialize(ctx context.Context, req *InitializeRequest) (*Empty, error) {
_, err := s.Init(ctx, &InitRequest{
Config: req.Config,
VerifyConnection: req.VerifyConnection,
})
return &Empty{}, err
}
func (s *gRPCServer) Init(ctx context.Context, req *InitRequest) (*InitResponse, error) {
config := map[string]interface{}{}
err := json.Unmarshal(req.Config, &config)
if err != nil {
return nil, err
}
resp, err := s.impl.Init(ctx, config, req.VerifyConnection)
if err != nil {
return nil, err
}
respConfig, err := json.Marshal(resp)
if err != nil {
return nil, err
}
return &InitResponse{
Config: respConfig,
}, err
}
func (s *gRPCServer) Close(_ context.Context, _ *Empty) (*Empty, error) {
s.impl.Close()
return &Empty{}, nil
}
// ---- gRPC client domain ----
type gRPCClient struct {
client DatabaseClient
clientConn *grpc.ClientConn
doneCtx context.Context
}
func (c *gRPCClient) Type() (string, error) {
resp, err := c.client.Type(c.doneCtx, &Empty{})
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
}
ctx, cancel := context.WithCancel(ctx)
quitCh := pluginutil.CtxCancelIfCanceled(cancel, c.doneCtx)
defer close(quitCh)
defer cancel()
resp, err := c.client.CreateUser(ctx, &CreateUserRequest{
Statements: &statements,
UsernameConfig: &usernameConfig,
Expiration: t,
})
if err != nil {
if c.doneCtx.Err() != nil {
return "", "", ErrPluginShutdown
}
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
}
ctx, cancel := context.WithCancel(ctx)
quitCh := pluginutil.CtxCancelIfCanceled(cancel, c.doneCtx)
defer close(quitCh)
defer cancel()
_, err = c.client.RenewUser(ctx, &RenewUserRequest{
Statements: &statements,
Username: username,
Expiration: t,
})
if err != nil {
if c.doneCtx.Err() != nil {
return ErrPluginShutdown
}
return err
}
return nil
}
func (c *gRPCClient) RevokeUser(ctx context.Context, statements Statements, username string) error {
ctx, cancel := context.WithCancel(ctx)
quitCh := pluginutil.CtxCancelIfCanceled(cancel, c.doneCtx)
defer close(quitCh)
defer cancel()
_, err := c.client.RevokeUser(ctx, &RevokeUserRequest{
Statements: &statements,
Username: username,
})
if err != nil {
if c.doneCtx.Err() != nil {
return ErrPluginShutdown
}
return err
}
return nil
}
func (c *gRPCClient) RotateRootCredentials(ctx context.Context, statements []string) (conf map[string]interface{}, err error) {
ctx, cancel := context.WithCancel(ctx)
quitCh := pluginutil.CtxCancelIfCanceled(cancel, c.doneCtx)
defer close(quitCh)
defer cancel()
resp, err := c.client.RotateRootCredentials(ctx, &RotateRootCredentialsRequest{
Statements: statements,
})
if err != nil {
if c.doneCtx.Err() != nil {
return nil, ErrPluginShutdown
}
return nil, err
}
if err := json.Unmarshal(resp.Config, &conf); err != nil {
return nil, err
}
return conf, nil
}
func (c *gRPCClient) Initialize(ctx context.Context, conf map[string]interface{}, verifyConnection bool) error {
_, err := c.Init(ctx, conf, verifyConnection)
return err
}
func (c *gRPCClient) Init(ctx context.Context, conf map[string]interface{}, verifyConnection bool) (map[string]interface{}, error) {
configRaw, err := json.Marshal(conf)
if err != nil {
return nil, err
}
ctx, cancel := context.WithCancel(ctx)
quitCh := pluginutil.CtxCancelIfCanceled(cancel, c.doneCtx)
defer close(quitCh)
defer cancel()
resp, err := c.client.Init(ctx, &InitRequest{
Config: configRaw,
VerifyConnection: verifyConnection,
})
if err != nil {
// Fall back to old call if not implemented
grpcStatus, ok := status.FromError(err)
if ok && grpcStatus.Code() == codes.Unimplemented {
_, err = c.client.Initialize(ctx, &InitializeRequest{
Config: configRaw,
VerifyConnection: verifyConnection,
})
if err == nil {
return conf, nil
}
}
if c.doneCtx.Err() != nil {
return nil, ErrPluginShutdown
}
return nil, err
}
if err := json.Unmarshal(resp.Config, &conf); err != nil {
return nil, err
}
return conf, nil
}
func (c *gRPCClient) Close() error {
_, err := c.client.Close(c.doneCtx, &Empty{})
return err
}

View File

@ -1,168 +0,0 @@
package dbplugin
import (
"context"
"fmt"
"time"
"google.golang.org/grpc"
"github.com/hashicorp/errwrap"
log "github.com/hashicorp/go-hclog"
plugin "github.com/hashicorp/go-plugin"
"github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/helper/pluginutil"
)
// Database is the interface that all database objects must implement.
type Database interface {
// Type returns the TypeName for the particular database backend
// implementation. This type name is usually set as a constant within the
// database backend implementation, e.g. "mysql" for the MySQL database
// backend.
Type() (string, error)
// CreateUser is called on `$ vault read database/creds/:role-name` and it's
// also the first time anything is touched from `$ vault write
// database/roles/:role-name`. This is likely to be the highest-throughput
// method for most plugins.
CreateUser(ctx context.Context, statements Statements, usernameConfig UsernameConfig, expiration time.Time) (username string, password string, err error)
// RenewUser is triggered by a renewal call to the API. In many database
// backends, this triggers a call on the underlying database that extends a
// VALID UNTIL clause on a user. However, if no such need exists, setting
// this as a NO-OP means that when renewal is called, the lease renewal time
// is pushed further out as appropriate, thus pushing out the time until the
// RevokeUser method is called.
RenewUser(ctx context.Context, statements Statements, username string, expiration time.Time) error
// RevokeUser is triggered either automatically by a lease expiration, or by
// a revocation call to the API.
RevokeUser(ctx context.Context, statements Statements, username string) error
// RotateRootCredentials is triggered by a root credential rotation call to
// the API.
RotateRootCredentials(ctx context.Context, statements []string) (config map[string]interface{}, err error)
// Init is called on `$ vault write database/config/:db-name`, or when you
// do a creds call after Vault's been restarted. The config provided won't
// hold all the keys and values provided in the API call, some will be
// stripped by the database engine before the config is provided. The config
// returned will be stored, which will persist it across shutdowns.
Init(ctx context.Context, config map[string]interface{}, verifyConnection bool) (saveConfig map[string]interface{}, err error)
// Close attempts to close the underlying database connection that was
// established by the backend.
Close() error
// DEPRECATED: Will be removed in a future plugin version bump.
// Initialize is a backwards-compatible implementation that simply calls
// Init, dropping the saveConfig, and returning the err.
Initialize(ctx context.Context, config map[string]interface{}, verifyConnection bool) (err error)
}
// PluginFactory is used to build plugin database types. It wraps the database
// object in a logging and metrics middleware.
func PluginFactory(ctx context.Context, pluginName string, sys pluginutil.LookRunnerUtil, logger log.Logger) (Database, error) {
// Look for plugin in the plugin catalog
pluginRunner, err := sys.LookupPlugin(ctx, pluginName, consts.PluginTypeDatabase)
if err != nil {
return nil, err
}
namedLogger := logger.Named(pluginName)
var transport string
var db Database
if pluginRunner.Builtin {
// Plugin is builtin so we can retrieve an instance of the interface
// from the pluginRunner. Then cast it to a Database.
dbRaw, err := pluginRunner.BuiltinFactory()
if err != nil {
return nil, errwrap.Wrapf("error initializing plugin: {{err}}", err)
}
var ok bool
db, ok = dbRaw.(Database)
if !ok {
return nil, fmt.Errorf("unsupported database type: %q", pluginName)
}
transport = "builtin"
} else {
// create a DatabasePluginClient instance
db, err = NewPluginClient(ctx, sys, pluginRunner, namedLogger, false)
if err != nil {
return nil, err
}
// Switch on the underlying database client type to get the transport
// method.
switch db.(*DatabasePluginClient).Database.(type) {
case *gRPCClient:
transport = "gRPC"
}
}
typeStr, err := db.Type()
if err != nil {
return nil, errwrap.Wrapf("error getting plugin type: {{err}}", err)
}
// Wrap with metrics middleware
db = &databaseMetricsMiddleware{
next: db,
typeStr: typeStr,
}
// Wrap with tracing middleware
if namedLogger.IsTrace() {
db = &databaseTracingMiddleware{
next: db,
logger: namedLogger.With("transport", transport),
}
}
return db, nil
}
// handshakeConfigs are used to just do a basic handshake between
// a plugin and host. If the handshake fails, a user friendly error is shown.
// This prevents users from executing bad plugins or executing a plugin
// directory. It is a UX feature, not a security feature.
var handshakeConfig = plugin.HandshakeConfig{
ProtocolVersion: 4,
MagicCookieKey: "VAULT_DATABASE_PLUGIN",
MagicCookieValue: "926a0820-aea2-be28-51d6-83cdf00e8edb",
}
var _ plugin.Plugin = &GRPCDatabasePlugin{}
var _ plugin.GRPCPlugin = &GRPCDatabasePlugin{}
// GRPCDatabasePlugin is the plugin.Plugin implementation that only supports GRPC
// transport
type GRPCDatabasePlugin struct {
Impl Database
// Embeding this will disable the netRPC protocol
plugin.NetRPCUnsupportedPlugin
}
func (d GRPCDatabasePlugin) GRPCServer(_ *plugin.GRPCBroker, s *grpc.Server) error {
impl := &DatabaseErrorSanitizerMiddleware{
next: d.Impl,
}
RegisterDatabaseServer(s, &gRPCServer{impl: impl})
return nil
}
func (GRPCDatabasePlugin) GRPCClient(doneCtx context.Context, _ *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {
return &gRPCClient{
client: NewDatabaseClient(c),
clientConn: c,
doneCtx: doneCtx,
}, nil
}

View File

@ -9,10 +9,9 @@ import (
log "github.com/hashicorp/go-hclog" log "github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/api" "github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
"github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/helper/namespace"
vaulthttp "github.com/hashicorp/vault/http" vaulthttp "github.com/hashicorp/vault/http"
"github.com/hashicorp/vault/plugins" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/sdk/helper/consts" "github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/helper/pluginutil" "github.com/hashicorp/vault/sdk/helper/pluginutil"
"github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/sdk/logical"
@ -113,11 +112,11 @@ func TestPlugin_GRPC_Main(t *testing.T) {
args := []string{"--tls-skip-verify=true"} args := []string{"--tls-skip-verify=true"}
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(args) flags.Parse(args)
plugins.Serve(plugin, apiClientMeta.GetTLSConfig()) dbplugin.Serve(plugin, api.VaultPluginTLSProvider(apiClientMeta.GetTLSConfig()))
} }
func TestPlugin_Init(t *testing.T) { func TestPlugin_Init(t *testing.T) {

View File

@ -1,43 +0,0 @@
package dbplugin
import (
"crypto/tls"
plugin "github.com/hashicorp/go-plugin"
)
// Serve is called from within a plugin and wraps the provided
// Database implementation in a databasePluginRPCServer object and starts a
// RPC server.
func Serve(db Database, tlsProvider func() (*tls.Config, error)) {
plugin.Serve(ServeConfig(db, tlsProvider))
}
func ServeConfig(db Database, tlsProvider func() (*tls.Config, error)) *plugin.ServeConfig {
// pluginSets is the map of plugins we can dispense.
pluginSets := map[int]plugin.PluginSet{
// Version 3 used to supports both protocols. We want to keep it around
// since it's possible old plugins built against this version will still
// work with gRPC. There is currently no difference between version 3
// and version 4.
3: plugin.PluginSet{
"database": &GRPCDatabasePlugin{
Impl: db,
},
},
4: plugin.PluginSet{
"database": &GRPCDatabasePlugin{
Impl: db,
},
},
}
conf := &plugin.ServeConfig{
HandshakeConfig: handshakeConfig,
VersionedPlugins: pluginSets,
TLSProvider: tlsProvider,
GRPCServer: plugin.DefaultGRPCServer,
}
return conf
}

View File

@ -9,7 +9,7 @@ import (
"github.com/fatih/structs" "github.com/fatih/structs"
uuid "github.com/hashicorp/go-uuid" uuid "github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/sdk/logical"
) )

View File

@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/helper/strutil"
"github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/sdk/logical"

View File

@ -4,7 +4,7 @@ import (
"context" "context"
"time" "time"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/helper/strutil"
"github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/sdk/logical"

View File

@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/sdk/logical"
) )

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -6,8 +6,8 @@ import (
"strings" "strings"
uuid "github.com/hashicorp/go-uuid" uuid "github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/helper/dbtxn"
"github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/dbtxn"
"github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/helper/strutil"
"github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/sdk/logical"
) )

View File

@ -6,8 +6,8 @@ import (
"fmt" "fmt"
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/helper/dbtxn"
"github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/dbtxn"
"github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/sdk/logical"
) )

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -6,8 +6,8 @@ import (
"strings" "strings"
uuid "github.com/hashicorp/go-uuid" uuid "github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/helper/dbtxn"
"github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/dbtxn"
"github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/helper/strutil"
"github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/sdk/logical"
_ "github.com/lib/pq" _ "github.com/lib/pq"

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -7,8 +7,8 @@ import (
"time" "time"
uuid "github.com/hashicorp/go-uuid" uuid "github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/helper/dbtxn"
"github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/dbtxn"
"github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/helper/strutil"
"github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/sdk/logical"
_ "github.com/lib/pq" _ "github.com/lib/pq"

View File

@ -8,8 +8,8 @@ import (
"time" "time"
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/helper/dbtxn"
"github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/dbtxn"
"github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/helper/strutil"
"github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/sdk/logical"
"github.com/lib/pq" "github.com/lib/pq"

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,7 +10,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -56,7 +56,7 @@ func TestBackend_PluginMain(t *testing.T) {
args = append(args, fmt.Sprintf("--ca-cert=%s", caPEM)) args = append(args, fmt.Sprintf("--ca-cert=%s", caPEM))
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(args) flags.Parse(args)
tlsConfig := apiClientMeta.GetTLSConfig() tlsConfig := apiClientMeta.GetTLSConfig()

View File

@ -19,9 +19,9 @@ import (
hclog "github.com/hashicorp/go-hclog" hclog "github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/api" "github.com/hashicorp/vault/api"
cachememdb "github.com/hashicorp/vault/command/agent/cache/cachememdb" cachememdb "github.com/hashicorp/vault/command/agent/cache/cachememdb"
"github.com/hashicorp/vault/helper/base62"
"github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/helper/namespace"
nshelper "github.com/hashicorp/vault/helper/namespace" nshelper "github.com/hashicorp/vault/helper/namespace"
"github.com/hashicorp/vault/sdk/helper/base62"
"github.com/hashicorp/vault/sdk/helper/consts" "github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/helper/cryptoutil" "github.com/hashicorp/vault/sdk/helper/cryptoutil"
"github.com/hashicorp/vault/sdk/helper/jsonutil" "github.com/hashicorp/vault/sdk/helper/jsonutil"

View File

@ -12,9 +12,9 @@ import (
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
uuid "github.com/hashicorp/go-uuid" uuid "github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/api" "github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/helper/base62"
"github.com/hashicorp/vault/helper/pgpkeys" "github.com/hashicorp/vault/helper/pgpkeys"
"github.com/hashicorp/vault/helper/xor" "github.com/hashicorp/vault/helper/xor"
"github.com/hashicorp/vault/sdk/helper/base62"
"github.com/hashicorp/vault/sdk/helper/password" "github.com/hashicorp/vault/sdk/helper/password"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
"github.com/posener/complete" "github.com/posener/complete"

View File

@ -17,8 +17,8 @@ import (
"github.com/go-test/deep" "github.com/go-test/deep"
log "github.com/hashicorp/go-hclog" log "github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/command/server" "github.com/hashicorp/vault/command/server"
"github.com/hashicorp/vault/helper/base62"
"github.com/hashicorp/vault/helper/testhelpers" "github.com/hashicorp/vault/helper/testhelpers"
"github.com/hashicorp/vault/sdk/helper/base62"
"github.com/hashicorp/vault/sdk/physical" "github.com/hashicorp/vault/sdk/physical"
"github.com/hashicorp/vault/vault" "github.com/hashicorp/vault/vault"
) )

29
go.mod
View File

@ -67,7 +67,6 @@ require (
github.com/hashicorp/go-hclog v0.8.0 github.com/hashicorp/go-hclog v0.8.0
github.com/hashicorp/go-memdb v1.0.0 github.com/hashicorp/go-memdb v1.0.0
github.com/hashicorp/go-multierror v1.0.0 github.com/hashicorp/go-multierror v1.0.0
github.com/hashicorp/go-plugin v1.0.0
github.com/hashicorp/go-rootcerts v1.0.0 github.com/hashicorp/go-rootcerts v1.0.0
github.com/hashicorp/go-sockaddr v1.0.2 github.com/hashicorp/go-sockaddr v1.0.2
github.com/hashicorp/go-syslog v1.0.0 github.com/hashicorp/go-syslog v1.0.0
@ -75,20 +74,20 @@ require (
github.com/hashicorp/golang-lru v0.5.1 github.com/hashicorp/golang-lru v0.5.1
github.com/hashicorp/hcl v1.0.0 github.com/hashicorp/hcl v1.0.0
github.com/hashicorp/nomad/api v0.0.0-20190412184103-1c38ced33adf github.com/hashicorp/nomad/api v0.0.0-20190412184103-1c38ced33adf
github.com/hashicorp/vault-plugin-auth-alicloud v0.5.0 github.com/hashicorp/vault-plugin-auth-alicloud v0.5.1
github.com/hashicorp/vault-plugin-auth-azure v0.5.0 github.com/hashicorp/vault-plugin-auth-azure v0.5.1
github.com/hashicorp/vault-plugin-auth-centrify v0.5.0 github.com/hashicorp/vault-plugin-auth-centrify v0.5.1
github.com/hashicorp/vault-plugin-auth-gcp v0.5.0 github.com/hashicorp/vault-plugin-auth-gcp v0.5.1
github.com/hashicorp/vault-plugin-auth-jwt v0.5.0 github.com/hashicorp/vault-plugin-auth-jwt v0.5.1
github.com/hashicorp/vault-plugin-auth-kubernetes v0.5.0 github.com/hashicorp/vault-plugin-auth-kubernetes v0.5.1
github.com/hashicorp/vault-plugin-secrets-ad v0.5.0 github.com/hashicorp/vault-plugin-secrets-ad v0.5.1
github.com/hashicorp/vault-plugin-secrets-alicloud v0.5.0 github.com/hashicorp/vault-plugin-secrets-alicloud v0.5.1
github.com/hashicorp/vault-plugin-secrets-azure v0.5.0 github.com/hashicorp/vault-plugin-secrets-azure v0.5.1
github.com/hashicorp/vault-plugin-secrets-gcp v0.5.0 github.com/hashicorp/vault-plugin-secrets-gcp v0.5.1
github.com/hashicorp/vault-plugin-secrets-gcpkms v0.5.0 github.com/hashicorp/vault-plugin-secrets-gcpkms v0.5.1
github.com/hashicorp/vault-plugin-secrets-kv v0.5.0 github.com/hashicorp/vault-plugin-secrets-kv v0.5.1
github.com/hashicorp/vault/api v1.0.0 github.com/hashicorp/vault/api v1.0.1
github.com/hashicorp/vault/sdk v0.1.7 github.com/hashicorp/vault/sdk v0.1.8
github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4 github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
github.com/jackc/pgx v3.3.0+incompatible // indirect github.com/jackc/pgx v3.3.0+incompatible // indirect

49
go.sum
View File

@ -274,30 +274,33 @@ github.com/hashicorp/nomad/api v0.0.0-20190412184103-1c38ced33adf h1:U/40PQvWkaX
github.com/hashicorp/nomad/api v0.0.0-20190412184103-1c38ced33adf/go.mod h1:BDngVi1f4UA6aJq9WYTgxhfWSE1+42xshvstLU2fRGk= github.com/hashicorp/nomad/api v0.0.0-20190412184103-1c38ced33adf/go.mod h1:BDngVi1f4UA6aJq9WYTgxhfWSE1+42xshvstLU2fRGk=
github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0= github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hashicorp/vault-plugin-auth-alicloud v0.5.0 h1:wz9UqUd83z96xzXMzMlRO+qMljyu5AgV2kYyQEaFusM= github.com/hashicorp/vault-plugin-auth-alicloud v0.5.1 h1:CldlLfMGlcXy+5CvnNsOWJjE9/C1i+Nho4ClSJe+63k=
github.com/hashicorp/vault-plugin-auth-alicloud v0.5.0/go.mod h1:m9UIpluGiLWWU60qbQ1AXNt6RD15kvgL7p93WGEE8CY= github.com/hashicorp/vault-plugin-auth-alicloud v0.5.1/go.mod h1:v0d6/ft2ESFHG/PB2pqcwDPlvtAWWfOmfsY0nfbIMy0=
github.com/hashicorp/vault-plugin-auth-azure v0.5.0 h1:SCC6gkPaMZnO4JJk+bMIf4QEWEiVjuBVcmM7sfgQgFg= github.com/hashicorp/vault-plugin-auth-azure v0.5.1 h1:1CTmC68zYhp/cKuHW8K0QbnWEetFK7UUu5jaWhmzbHw=
github.com/hashicorp/vault-plugin-auth-azure v0.5.0/go.mod h1:ISyvQfA+G1Wo57geBEGrh+rBRaTJph65+cCpyL9y3SM= github.com/hashicorp/vault-plugin-auth-azure v0.5.1/go.mod h1:D/slkpcqcZMqslj1X9jfU9aIOrC41LVkfDQ9lFhYg0o=
github.com/hashicorp/vault-plugin-auth-centrify v0.5.0 h1:1BkJBJ72nGCz5XTHFrIMV7pyWmbCO7T/5DNhs6Ka+Sg= github.com/hashicorp/vault-plugin-auth-centrify v0.5.1 h1:kHWphxtASUJVYgqvfr6KjCN74qWLJeLhSRE5kBQ4iiQ=
github.com/hashicorp/vault-plugin-auth-centrify v0.5.0/go.mod h1:5LJVb/fR3QIFI3ctn+ylMo+C46YGXRYXbg5l+2OC87A= github.com/hashicorp/vault-plugin-auth-centrify v0.5.1/go.mod h1:GHplZPj7NfPWdeCkgTRnNzbjVP5IW5MNm7+MMsjobpQ=
github.com/hashicorp/vault-plugin-auth-gcp v0.5.0 h1:7mydlUN3w1LL7eKpy7i6Zzta8f0nDmBo8jxAaj1eBfg= github.com/hashicorp/vault-plugin-auth-gcp v0.5.0 h1:7mydlUN3w1LL7eKpy7i6Zzta8f0nDmBo8jxAaj1eBfg=
github.com/hashicorp/vault-plugin-auth-gcp v0.5.0/go.mod h1:ll5vk2qVxmCzzDM+gl2Qdd9vGOf2FyUg9hspbyvBpQ0= github.com/hashicorp/vault-plugin-auth-gcp v0.5.0/go.mod h1:ll5vk2qVxmCzzDM+gl2Qdd9vGOf2FyUg9hspbyvBpQ0=
github.com/hashicorp/vault-plugin-auth-jwt v0.5.0 h1:NGXKnn+VObN7Wmy8ZW1mQw1E5zSuv9A8Nco07yETpH4= github.com/hashicorp/vault-plugin-auth-gcp v0.5.1 h1:8DR00s+Wmc21i3sfzvsqW88VMdf6NI2ue+onGoHshww=
github.com/hashicorp/vault-plugin-auth-jwt v0.5.0/go.mod h1:yPCRQbpM5Tjg2q9jGWUpmgEGbvGU/LQ4AXVXgDuNJD8= github.com/hashicorp/vault-plugin-auth-gcp v0.5.1/go.mod h1:eLj92eX8MPI4vY1jaazVLF2sVbSAJ3LRHLRhF/pUmlI=
github.com/hashicorp/vault-plugin-auth-kubernetes v0.5.0 h1:vo4ppQrEmSDQjFz4kLmSdeapVmgMGnRPvNKyerfoWvA= github.com/hashicorp/vault-plugin-auth-jwt v0.5.1 h1:d9WLI7oF6VMtwBZwS5bbChc4kW+UwNZUKIGXH6wnnTc=
github.com/hashicorp/vault-plugin-auth-kubernetes v0.5.0/go.mod h1:cZj//LdJ5DW6Kt+X+DEe/k6vdtNDP8fwET8g38++2pU= github.com/hashicorp/vault-plugin-auth-jwt v0.5.1/go.mod h1:5VU7gc6/BEEFQW/viqMs3LBxI1D1cxJmKqKQEP3JUP4=
github.com/hashicorp/vault-plugin-secrets-ad v0.5.0 h1:WyUKWfhIZioVjz1QmSiasy3gTjrbJv0MjEiFZ8C/eeQ= github.com/hashicorp/vault-plugin-auth-kubernetes v0.5.1 h1:q6DGb12Vw/CpZ9xDWAmpzxVRKeClFqRFgbIZ3fZcvuY=
github.com/hashicorp/vault-plugin-secrets-ad v0.5.0/go.mod h1:WmGEMGORK89KYcyDvWFplTuMW390alTzbkZvTRXoU7c= github.com/hashicorp/vault-plugin-auth-kubernetes v0.5.1/go.mod h1:qCDsm0njdfUrnN5sFKMLjxGjZKjQf2qB6dReQ4gr4YI=
github.com/hashicorp/vault-plugin-secrets-alicloud v0.5.0 h1:ewf07WNRNq3gtZZMiquas+f/OlAVK11j+zJan4xI19Q= github.com/hashicorp/vault-plugin-secrets-ad v0.5.1 h1:BdiASUZLOvOUs317EnaUNjGxTSw0PYGQA7zJZhDKLC4=
github.com/hashicorp/vault-plugin-secrets-alicloud v0.5.0/go.mod h1:kRuTqhroXcplElZa5rA4DfEh6Ae3DPHuFWiL/kDegLM= github.com/hashicorp/vault-plugin-secrets-ad v0.5.1/go.mod h1:EH9CI8+0aWRBz8eIgGth0QjttmHWlGvn+8ZmX/ZUetE=
github.com/hashicorp/vault-plugin-secrets-azure v0.5.0 h1:/lru2wFWqQcXuU2BkL1wmPd64OnSlWjQJSlM+Ia72ls= github.com/hashicorp/vault-plugin-secrets-alicloud v0.5.1 h1:72K91p4uLhT/jgtBq2zV5Wn8ocvny4sAN56XOcTxK1w=
github.com/hashicorp/vault-plugin-secrets-azure v0.5.0/go.mod h1:ETT9lHxMk+rrACbsDrM+YzJ8upURhC+7CRyXrStBeII= github.com/hashicorp/vault-plugin-secrets-alicloud v0.5.1/go.mod h1:MspbyD2pPrYgBnYIawkBsFinaDb9lx9PA6uBYOG+d8I=
github.com/hashicorp/vault-plugin-secrets-gcp v0.5.0 h1:92FGSp6mYtT59XExLBJeAGy/vmN3XY7zpaVnvRnMGHg= github.com/hashicorp/vault-plugin-secrets-azure v0.5.1 h1:6XFAkvpQl4zrXpZLSW9TCfF2z0mb2vwbrNmX2nzn480=
github.com/hashicorp/vault-plugin-secrets-gcp v0.5.0/go.mod h1:8Fldfy8Dae4RXd1Z4WfRIvXbmD6MLeieoODDotOY8jc= github.com/hashicorp/vault-plugin-secrets-azure v0.5.1/go.mod h1:9D3lbhWkN7kTCIrQl8yxMU4IkisAY3SYZaRvseih6ZE=
github.com/hashicorp/vault-plugin-secrets-gcpkms v0.5.0 h1:SNCIpLEN9sLIw5PMY2Gw3O91WOwC1DikcWx2yQXb+wg= github.com/hashicorp/vault-plugin-secrets-gcp v0.5.1 h1:u4rOnhR1iLNxgi03bhJeNpdAr+2YVVOdYgN0IWztj+Q=
github.com/hashicorp/vault-plugin-secrets-gcpkms v0.5.0/go.mod h1:6kWea8qrrjq/7WwfB0Vr4/Wf/rTcYQAD6rDZhpnB9xI= github.com/hashicorp/vault-plugin-secrets-gcp v0.5.1/go.mod h1:kVy5kaH4qjHX6d2eB3zPI/h/6edpNBF8LBoRC6zEbbs=
github.com/hashicorp/vault-plugin-secrets-kv v0.5.0 h1:YEtOOvboPmATo/ESzIwMs3YyuZnlt7Oltdrwy9c5cBg= github.com/hashicorp/vault-plugin-secrets-gcpkms v0.5.1 h1:v25YWb7eMPe9DjGsUexRRuWwPlFNh+lbEGOeNrZalf8=
github.com/hashicorp/vault-plugin-secrets-kv v0.5.0/go.mod h1:NILaahjnYpYnZ3HQXn4rFBSvtYjW9MAtGsjcTf50AOk= github.com/hashicorp/vault-plugin-secrets-gcpkms v0.5.1/go.mod h1:seBkt6x33ZT20koMcUwV/viMomnXDipsLgK5KUKz2ik=
github.com/hashicorp/vault-plugin-secrets-kv v0.5.1 h1:awaZ/UoeiDD0j3xF1E0kmXWJvAZw8ULayQu46mB6Un4=
github.com/hashicorp/vault-plugin-secrets-kv v0.5.1/go.mod h1:PIjaafaRr2QlkGl2SNhIywxlejeW0iMUtmx8u9u/a6c=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
@ -418,6 +421,8 @@ github.com/ory/dockertest v3.3.4+incompatible h1:VrpM6Gqg7CrPm3bL4Wm1skO+zFWLbh7
github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=

View File

@ -1,41 +0,0 @@
// Package base62 provides utilities for working with base62 strings.
// base62 strings will only contain characters: 0-9, a-z, A-Z
package base62
import (
uuid "github.com/hashicorp/go-uuid"
)
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
const csLen = byte(len(charset))
// Random generates a random string using base-62 characters.
// Resulting entropy is ~5.95 bits/character.
func Random(length int) (string, error) {
if length == 0 {
return "", nil
}
output := make([]byte, 0, length)
// Request a bit more than length to reduce the chance
// of needing more than one batch of random bytes
batchSize := length + length/4
for {
buf, err := uuid.GenerateRandomBytes(batchSize)
if err != nil {
return "", err
}
for _, b := range buf {
// Avoid bias by using a value range that's a multiple of 62
if b < (csLen * 4) {
output = append(output, charset[b%csLen])
if len(output) == length {
return string(output), nil
}
}
}
}
}

View File

@ -1,31 +0,0 @@
package base62
import (
"testing"
)
func TestRandom(t *testing.T) {
strings := make(map[string]struct{})
for i := 0; i < 100000; i++ {
c, err := Random(16)
if err != nil {
t.Fatal(err)
}
if _, ok := strings[c]; ok {
t.Fatalf("Unexpected duplicate string: %s", c)
}
strings[c] = struct{}{}
}
for i := 0; i < 3000; i++ {
c, err := Random(i)
if err != nil {
t.Fatal(err)
}
if len(c) != i {
t.Fatalf("Expected length %d, got: %d", i, len(c))
}
}
}

View File

@ -1,7 +1,7 @@
package builtinplugins package builtinplugins
import ( import (
"github.com/hashicorp/vault/plugins/helper/database/credsutil" "github.com/hashicorp/vault/sdk/database/helper/credsutil"
"github.com/hashicorp/vault/sdk/helper/consts" "github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/sdk/logical"

View File

@ -1,63 +0,0 @@
package dbtxn
import (
"context"
"database/sql"
"fmt"
"strings"
)
// ExecuteDBQuery handles executing one single statement, while properly releasing its resources.
// - ctx: Required
// - db: Required
// - config: Optional, may be nil
// - query: Required
func ExecuteDBQuery(ctx context.Context, db *sql.DB, params map[string]string, query string) error {
parsedQuery := parseQuery(params, query)
stmt, err := db.PrepareContext(ctx, parsedQuery)
if err != nil {
return err
}
defer stmt.Close()
return execute(ctx, stmt)
}
// ExecuteTxQuery handles executing one single statement, while properly releasing its resources.
// - ctx: Required
// - tx: Required
// - config: Optional, may be nil
// - query: Required
func ExecuteTxQuery(ctx context.Context, tx *sql.Tx, params map[string]string, query string) error {
parsedQuery := parseQuery(params, query)
stmt, err := tx.PrepareContext(ctx, parsedQuery)
if err != nil {
return err
}
defer stmt.Close()
return execute(ctx, stmt)
}
func execute(ctx context.Context, stmt *sql.Stmt) error {
if _, err := stmt.ExecContext(ctx); err != nil {
return err
}
return nil
}
func parseQuery(m map[string]string, tpl string) string {
if m == nil || len(m) <= 0 {
return tpl
}
for k, v := range m {
tpl = strings.Replace(tpl, fmt.Sprintf("{{%s}}", k), v, -1)
}
return tpl
}

View File

@ -76,7 +76,7 @@ func TestPlugin_PluginMain(t *testing.T) {
args := []string{"--ca-cert=" + caPEM} args := []string{"--ca-cert=" + caPEM}
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(args) flags.Parse(args)

View File

@ -8,7 +8,7 @@ import (
"io" "io"
"net/http" "net/http"
"github.com/hashicorp/vault/helper/base62" "github.com/hashicorp/vault/sdk/helper/base62"
"github.com/hashicorp/vault/vault" "github.com/hashicorp/vault/vault"
) )

View File

@ -9,7 +9,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -8,10 +8,9 @@ import (
"github.com/gocql/gocql" "github.com/gocql/gocql"
multierror "github.com/hashicorp/go-multierror" multierror "github.com/hashicorp/go-multierror"
"github.com/hashicorp/vault/api" "github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/plugins" "github.com/hashicorp/vault/sdk/database/helper/credsutil"
"github.com/hashicorp/vault/plugins/helper/database/credsutil" "github.com/hashicorp/vault/sdk/database/helper/dbutil"
"github.com/hashicorp/vault/plugins/helper/database/dbutil"
"github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/helper/strutil"
) )
@ -62,7 +61,7 @@ func Run(apiTLSConfig *api.TLSConfig) error {
return err return err
} }
plugins.Serve(dbType.(dbplugin.Database), apiTLSConfig) dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig))
return nil return nil
} }

View File

@ -11,7 +11,7 @@ import (
"github.com/gocql/gocql" "github.com/gocql/gocql"
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/ory/dockertest" "github.com/ory/dockertest"
) )

View File

@ -12,8 +12,8 @@ import (
"github.com/gocql/gocql" "github.com/gocql/gocql"
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/plugins/helper/database/connutil" "github.com/hashicorp/vault/sdk/database/helper/connutil"
"github.com/hashicorp/vault/plugins/helper/database/dbutil" "github.com/hashicorp/vault/sdk/database/helper/dbutil"
"github.com/hashicorp/vault/sdk/helper/certutil" "github.com/hashicorp/vault/sdk/helper/certutil"
"github.com/hashicorp/vault/sdk/helper/parseutil" "github.com/hashicorp/vault/sdk/helper/parseutil"
"github.com/hashicorp/vault/sdk/helper/tlsutil" "github.com/hashicorp/vault/sdk/helper/tlsutil"

View File

@ -9,7 +9,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,12 +10,11 @@ import (
_ "github.com/SAP/go-hdb/driver" _ "github.com/SAP/go-hdb/driver"
"github.com/hashicorp/vault/api" "github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/helper/dbtxn" "github.com/hashicorp/vault/sdk/database/helper/connutil"
"github.com/hashicorp/vault/plugins" "github.com/hashicorp/vault/sdk/database/helper/credsutil"
"github.com/hashicorp/vault/plugins/helper/database/connutil" "github.com/hashicorp/vault/sdk/database/helper/dbutil"
"github.com/hashicorp/vault/plugins/helper/database/credsutil" "github.com/hashicorp/vault/sdk/helper/dbtxn"
"github.com/hashicorp/vault/plugins/helper/database/dbutil"
"github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/helper/strutil"
) )
@ -64,7 +63,7 @@ func Run(apiTLSConfig *api.TLSConfig) error {
return err return err
} }
plugins.Serve(dbType.(dbplugin.Database), apiTLSConfig) dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig))
return nil return nil
} }

View File

@ -9,7 +9,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
) )
func TestHANA_Initialize(t *testing.T) { func TestHANA_Initialize(t *testing.T) {

View File

@ -8,7 +8,7 @@ import (
"time" "time"
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/plugins/helper/database/connutil" "github.com/hashicorp/vault/sdk/database/helper/connutil"
"github.com/hashicorp/vault/sdk/helper/certutil" "github.com/hashicorp/vault/sdk/helper/certutil"
"github.com/hashicorp/vault/sdk/helper/parseutil" "github.com/hashicorp/vault/sdk/helper/parseutil"
"github.com/hashicorp/vault/sdk/helper/tlsutil" "github.com/hashicorp/vault/sdk/helper/tlsutil"

View File

@ -9,7 +9,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -7,10 +7,9 @@ import (
multierror "github.com/hashicorp/go-multierror" multierror "github.com/hashicorp/go-multierror"
"github.com/hashicorp/vault/api" "github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/plugins" "github.com/hashicorp/vault/sdk/database/helper/credsutil"
"github.com/hashicorp/vault/plugins/helper/database/credsutil" "github.com/hashicorp/vault/sdk/database/helper/dbutil"
"github.com/hashicorp/vault/plugins/helper/database/dbutil"
"github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/helper/strutil"
influx "github.com/influxdata/influxdb/client/v2" influx "github.com/influxdata/influxdb/client/v2"
) )
@ -62,7 +61,7 @@ func Run(apiTLSConfig *api.TLSConfig) error {
return err return err
} }
plugins.Serve(dbType.(dbplugin.Database), apiTLSConfig) dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig))
return nil return nil
} }

View File

@ -9,7 +9,7 @@ import (
"time" "time"
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
influx "github.com/influxdata/influxdb/client/v2" influx "github.com/influxdata/influxdb/client/v2"
"github.com/ory/dockertest" "github.com/ory/dockertest"
) )

View File

@ -15,8 +15,8 @@ import (
"time" "time"
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/plugins/helper/database/connutil" "github.com/hashicorp/vault/sdk/database/helper/connutil"
"github.com/hashicorp/vault/plugins/helper/database/dbutil" "github.com/hashicorp/vault/sdk/database/helper/dbutil"
"github.com/mitchellh/mapstructure" "github.com/mitchellh/mapstructure"
mgo "gopkg.in/mgo.v2" mgo "gopkg.in/mgo.v2"

View File

@ -9,7 +9,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -13,10 +13,9 @@ import (
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/api" "github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/plugins" "github.com/hashicorp/vault/sdk/database/helper/credsutil"
"github.com/hashicorp/vault/plugins/helper/database/credsutil" "github.com/hashicorp/vault/sdk/database/helper/dbutil"
"github.com/hashicorp/vault/plugins/helper/database/dbutil"
mgo "gopkg.in/mgo.v2" mgo "gopkg.in/mgo.v2"
) )
@ -61,7 +60,7 @@ func Run(apiTLSConfig *api.TLSConfig) error {
return err return err
} }
plugins.Serve(dbType.(*MongoDB), apiTLSConfig) dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig))
return nil return nil
} }

View File

@ -11,7 +11,7 @@ import (
"strings" "strings"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/ory/dockertest" "github.com/ory/dockertest"
) )

View File

@ -9,7 +9,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -12,12 +12,11 @@ import (
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
multierror "github.com/hashicorp/go-multierror" multierror "github.com/hashicorp/go-multierror"
"github.com/hashicorp/vault/api" "github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/helper/dbtxn" "github.com/hashicorp/vault/sdk/database/helper/connutil"
"github.com/hashicorp/vault/plugins" "github.com/hashicorp/vault/sdk/database/helper/credsutil"
"github.com/hashicorp/vault/plugins/helper/database/connutil" "github.com/hashicorp/vault/sdk/database/helper/dbutil"
"github.com/hashicorp/vault/plugins/helper/database/credsutil" "github.com/hashicorp/vault/sdk/helper/dbtxn"
"github.com/hashicorp/vault/plugins/helper/database/dbutil"
"github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/helper/strutil"
) )
@ -63,7 +62,7 @@ func Run(apiTLSConfig *api.TLSConfig) error {
return err return err
} }
plugins.Serve(dbType.(dbplugin.Database), apiTLSConfig) dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig))
return nil return nil
} }

View File

@ -9,7 +9,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
) )
func TestMSSQL_Initialize(t *testing.T) { func TestMSSQL_Initialize(t *testing.T) {

View File

@ -9,7 +9,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -9,7 +9,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -9,11 +9,10 @@ import (
stdmysql "github.com/go-sql-driver/mysql" stdmysql "github.com/go-sql-driver/mysql"
"github.com/hashicorp/vault/api" "github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/plugins" "github.com/hashicorp/vault/sdk/database/helper/connutil"
"github.com/hashicorp/vault/plugins/helper/database/connutil" "github.com/hashicorp/vault/sdk/database/helper/credsutil"
"github.com/hashicorp/vault/plugins/helper/database/credsutil" "github.com/hashicorp/vault/sdk/database/helper/dbutil"
"github.com/hashicorp/vault/plugins/helper/database/dbutil"
"github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/helper/strutil"
) )
@ -94,7 +93,7 @@ func runCommon(legacy bool, apiTLSConfig *api.TLSConfig) error {
return err return err
} }
plugins.Serve(dbType.(dbplugin.Database), apiTLSConfig) dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig))
return nil return nil
} }

View File

@ -9,9 +9,9 @@ import (
"testing" "testing"
"time" "time"
"github.com/hashicorp/vault/plugins/helper/database/credsutil" "github.com/hashicorp/vault/sdk/database/helper/credsutil"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/ory/dockertest" "github.com/ory/dockertest"
) )

View File

@ -9,7 +9,7 @@ import (
) )
func main() { func main() {
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(os.Args[1:]) flags.Parse(os.Args[1:])

View File

@ -10,12 +10,11 @@ import (
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/api" "github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/helper/dbtxn" "github.com/hashicorp/vault/sdk/database/helper/connutil"
"github.com/hashicorp/vault/plugins" "github.com/hashicorp/vault/sdk/database/helper/credsutil"
"github.com/hashicorp/vault/plugins/helper/database/connutil" "github.com/hashicorp/vault/sdk/database/helper/dbutil"
"github.com/hashicorp/vault/plugins/helper/database/credsutil" "github.com/hashicorp/vault/sdk/helper/dbtxn"
"github.com/hashicorp/vault/plugins/helper/database/dbutil"
"github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/helper/strutil"
"github.com/lib/pq" "github.com/lib/pq"
) )
@ -66,7 +65,7 @@ func Run(apiTLSConfig *api.TLSConfig) error {
return err return err
} }
plugins.Serve(dbType.(dbplugin.Database), apiTLSConfig) dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig))
return nil return nil
} }

View File

@ -10,7 +10,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/ory/dockertest" "github.com/ory/dockertest"
) )

View File

@ -1,25 +0,0 @@
package connutil
import (
"context"
"errors"
"sync"
)
var (
ErrNotInitialized = errors.New("connection has not been initialized")
)
// ConnectionProducer can be used as an embedded interface in the Database
// definition. It implements the methods dealing with individual database
// connections and is used in all the builtin database types.
type ConnectionProducer interface {
Close() error
Init(context.Context, map[string]interface{}, bool) (map[string]interface{}, error)
Connection(context.Context) (interface{}, error)
sync.Locker
// DEPRECATED, will be removed in 0.12
Initialize(context.Context, map[string]interface{}, bool) error
}

View File

@ -1,164 +0,0 @@
package connutil
import (
"context"
"database/sql"
"fmt"
"strings"
"sync"
"time"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/plugins/helper/database/dbutil"
"github.com/hashicorp/vault/sdk/helper/parseutil"
"github.com/mitchellh/mapstructure"
)
var _ ConnectionProducer = &SQLConnectionProducer{}
// SQLConnectionProducer implements ConnectionProducer and provides a generic producer for most sql databases
type SQLConnectionProducer struct {
ConnectionURL string `json:"connection_url" mapstructure:"connection_url" structs:"connection_url"`
MaxOpenConnections int `json:"max_open_connections" mapstructure:"max_open_connections" structs:"max_open_connections"`
MaxIdleConnections int `json:"max_idle_connections" mapstructure:"max_idle_connections" structs:"max_idle_connections"`
MaxConnectionLifetimeRaw interface{} `json:"max_connection_lifetime" mapstructure:"max_connection_lifetime" structs:"max_connection_lifetime"`
Username string `json:"username" mapstructure:"username" structs:"username"`
Password string `json:"password" mapstructure:"password" structs:"password"`
Type string
RawConfig map[string]interface{}
maxConnectionLifetime time.Duration
Initialized bool
db *sql.DB
sync.Mutex
}
func (c *SQLConnectionProducer) Initialize(ctx context.Context, conf map[string]interface{}, verifyConnection bool) error {
_, err := c.Init(ctx, conf, verifyConnection)
return err
}
func (c *SQLConnectionProducer) Init(ctx context.Context, conf map[string]interface{}, verifyConnection bool) (map[string]interface{}, error) {
c.Lock()
defer c.Unlock()
c.RawConfig = conf
err := mapstructure.WeakDecode(conf, &c)
if err != nil {
return nil, err
}
if len(c.ConnectionURL) == 0 {
return nil, fmt.Errorf("connection_url cannot be empty")
}
c.ConnectionURL = dbutil.QueryHelper(c.ConnectionURL, map[string]string{
"username": c.Username,
"password": c.Password,
})
if c.MaxOpenConnections == 0 {
c.MaxOpenConnections = 2
}
if c.MaxIdleConnections == 0 {
c.MaxIdleConnections = c.MaxOpenConnections
}
if c.MaxIdleConnections > c.MaxOpenConnections {
c.MaxIdleConnections = c.MaxOpenConnections
}
if c.MaxConnectionLifetimeRaw == nil {
c.MaxConnectionLifetimeRaw = "0s"
}
c.maxConnectionLifetime, err = parseutil.ParseDurationSecond(c.MaxConnectionLifetimeRaw)
if err != nil {
return nil, errwrap.Wrapf("invalid max_connection_lifetime: {{err}}", err)
}
// Set initialized to true at this point since all fields are set,
// and the connection can be established at a later time.
c.Initialized = true
if verifyConnection {
if _, err := c.Connection(ctx); err != nil {
return nil, errwrap.Wrapf("error verifying connection: {{err}}", err)
}
if err := c.db.PingContext(ctx); err != nil {
return nil, errwrap.Wrapf("error verifying connection: {{err}}", err)
}
}
return c.RawConfig, nil
}
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.PingContext(ctx); err == nil {
return c.db, nil
}
// If the ping was unsuccessful, close it and ignore errors as we'll be
// reestablishing anyways
c.db.Close()
}
// For mssql backend, switch to sqlserver instead
dbType := c.Type
if c.Type == "mssql" {
dbType = "sqlserver"
}
// Otherwise, attempt to make connection
conn := c.ConnectionURL
// Ensure timezone is set to UTC for all the connections
if strings.HasPrefix(conn, "postgres://") || strings.HasPrefix(conn, "postgresql://") {
if strings.Contains(conn, "?") {
conn += "&timezone=utc"
} else {
conn += "?timezone=utc"
}
}
var err error
c.db, err = sql.Open(dbType, conn)
if err != nil {
return nil, err
}
// Set some connection pool settings. We don't need much of this,
// since the request rate shouldn't be high.
c.db.SetMaxOpenConns(c.MaxOpenConnections)
c.db.SetMaxIdleConns(c.MaxIdleConnections)
c.db.SetConnMaxLifetime(c.maxConnectionLifetime)
return c.db, nil
}
func (c *SQLConnectionProducer) SecretValues() map[string]interface{} {
return map[string]interface{}{
c.Password: "[password]",
}
}
// Close attempts to close the connection
func (c *SQLConnectionProducer) Close() error {
// Grab the write lock
c.Lock()
defer c.Unlock()
if c.db != nil {
c.db.Close()
}
c.db = nil
return nil
}

View File

@ -1,46 +0,0 @@
package credsutil
import (
"time"
"fmt"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
"github.com/hashicorp/vault/helper/base62"
)
// CredentialsProducer can be used as an embedded interface in the Database
// definition. It implements the methods for generating user information for a
// particular database type and is used in all the builtin database types.
type CredentialsProducer interface {
GenerateUsername(usernameConfig dbplugin.UsernameConfig) (string, error)
GeneratePassword() (string, error)
GenerateExpiration(ttl time.Time) (string, error)
}
const (
reqStr = `A1a-`
minStrLen = 10
)
// RandomAlphaNumeric returns a random string of characters [A-Za-z0-9-]
// of the provided length. The string generated takes up to 4 characters
// of space that are predefined and prepended to ensure password
// character requirements. It also requires a min length of 10 characters.
func RandomAlphaNumeric(length int, prependA1a bool) (string, error) {
if length < minStrLen {
return "", fmt.Errorf("minimum length of %d is required", minStrLen)
}
var prefix string
if prependA1a {
prefix = reqStr
}
randomStr, err := base62.Random(length - len(prefix))
if err != nil {
return "", err
}
return prefix + randomStr, nil
}

View File

@ -1,40 +0,0 @@
package credsutil
import (
"strings"
"testing"
)
func TestRandomAlphaNumeric(t *testing.T) {
s, err := RandomAlphaNumeric(10, true)
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
if len(s) != 10 {
t.Fatalf("Unexpected length of string, expected 10, got string: %s", s)
}
s, err = RandomAlphaNumeric(20, true)
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
if len(s) != 20 {
t.Fatalf("Unexpected length of string, expected 20, got string: %s", s)
}
if !strings.Contains(s, reqStr) {
t.Fatalf("Expected %s to contain %s", s, reqStr)
}
s, err = RandomAlphaNumeric(20, false)
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
if len(s) != 20 {
t.Fatalf("Unexpected length of string, expected 20, got string: %s", s)
}
if strings.Contains(s, reqStr) {
t.Fatalf("Expected %s not to contain %s", s, reqStr)
}
}

View File

@ -1,72 +0,0 @@
package credsutil
import (
"fmt"
"time"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
)
const (
NoneLength int = -1
)
// SQLCredentialsProducer implements CredentialsProducer and provides a generic credentials producer for most sql database types.
type SQLCredentialsProducer struct {
DisplayNameLen int
RoleNameLen int
UsernameLen int
Separator string
}
func (scp *SQLCredentialsProducer) GenerateUsername(config dbplugin.UsernameConfig) (string, error) {
username := "v"
displayName := config.DisplayName
if scp.DisplayNameLen > 0 && len(displayName) > scp.DisplayNameLen {
displayName = displayName[:scp.DisplayNameLen]
} else if scp.DisplayNameLen == NoneLength {
displayName = ""
}
if len(displayName) > 0 {
username = fmt.Sprintf("%s%s%s", username, scp.Separator, displayName)
}
roleName := config.RoleName
if scp.RoleNameLen > 0 && len(roleName) > scp.RoleNameLen {
roleName = roleName[:scp.RoleNameLen]
} else if scp.RoleNameLen == NoneLength {
roleName = ""
}
if len(roleName) > 0 {
username = fmt.Sprintf("%s%s%s", username, scp.Separator, roleName)
}
userUUID, err := RandomAlphaNumeric(20, false)
if err != nil {
return "", err
}
username = fmt.Sprintf("%s%s%s", username, scp.Separator, userUUID)
username = fmt.Sprintf("%s%s%s", username, scp.Separator, fmt.Sprint(time.Now().Unix()))
if scp.UsernameLen > 0 && len(username) > scp.UsernameLen {
username = username[:scp.UsernameLen]
}
return username, nil
}
func (scp *SQLCredentialsProducer) GeneratePassword() (string, error) {
password, err := RandomAlphaNumeric(20, true)
if err != nil {
return "", err
}
return password, nil
}
func (scp *SQLCredentialsProducer) GenerateExpiration(ttl time.Time) (string, error) {
return ttl.Format("2006-01-02 15:04:05-0700"), nil
}

View File

@ -1,52 +0,0 @@
package dbutil
import (
"errors"
"fmt"
"strings"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
)
var (
ErrEmptyCreationStatement = errors.New("empty creation statements")
)
// Query templates a query for us.
func QueryHelper(tpl string, data map[string]string) string {
for k, v := range data {
tpl = strings.Replace(tpl, fmt.Sprintf("{{%s}}", k), v, -1)
}
return tpl
}
// StatementCompatibilityHelper will populate the statements fields to support
// compatibility
func StatementCompatibilityHelper(statements dbplugin.Statements) dbplugin.Statements {
switch {
case len(statements.Creation) > 0 && len(statements.CreationStatements) == 0:
statements.CreationStatements = strings.Join(statements.Creation, ";")
case len(statements.CreationStatements) > 0:
statements.Creation = []string{statements.CreationStatements}
}
switch {
case len(statements.Revocation) > 0 && len(statements.RevocationStatements) == 0:
statements.RevocationStatements = strings.Join(statements.Revocation, ";")
case len(statements.RevocationStatements) > 0:
statements.Revocation = []string{statements.RevocationStatements}
}
switch {
case len(statements.Renewal) > 0 && len(statements.RenewStatements) == 0:
statements.RenewStatements = strings.Join(statements.Renewal, ";")
case len(statements.RenewStatements) > 0:
statements.Renewal = []string{statements.RenewStatements}
}
switch {
case len(statements.Rollback) > 0 && len(statements.RollbackStatements) == 0:
statements.RollbackStatements = strings.Join(statements.Rollback, ";")
case len(statements.RollbackStatements) > 0:
statements.Rollback = []string{statements.RollbackStatements}
}
return statements
}

View File

@ -1,62 +0,0 @@
package dbutil
import (
"reflect"
"testing"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
)
func TestStatementCompatibilityHelper(t *testing.T) {
const (
creationStatement = "creation"
renewStatement = "renew"
revokeStatement = "revoke"
rollbackStatement = "rollback"
)
expectedStatements := dbplugin.Statements{
Creation: []string{creationStatement},
Rollback: []string{rollbackStatement},
Revocation: []string{revokeStatement},
Renewal: []string{renewStatement},
CreationStatements: creationStatement,
RenewStatements: renewStatement,
RollbackStatements: rollbackStatement,
RevocationStatements: revokeStatement,
}
statements1 := dbplugin.Statements{
CreationStatements: creationStatement,
RenewStatements: renewStatement,
RollbackStatements: rollbackStatement,
RevocationStatements: revokeStatement,
}
if !reflect.DeepEqual(expectedStatements, StatementCompatibilityHelper(statements1)) {
t.Fatalf("mismatch: %#v, %#v", expectedStatements, statements1)
}
statements2 := dbplugin.Statements{
Creation: []string{creationStatement},
Rollback: []string{rollbackStatement},
Revocation: []string{revokeStatement},
Renewal: []string{renewStatement},
}
if !reflect.DeepEqual(expectedStatements, StatementCompatibilityHelper(statements2)) {
t.Fatalf("mismatch: %#v, %#v", expectedStatements, statements2)
}
statements3 := dbplugin.Statements{
CreationStatements: creationStatement,
}
expectedStatements3 := dbplugin.Statements{
Creation: []string{creationStatement},
CreationStatements: creationStatement,
}
if !reflect.DeepEqual(expectedStatements3, StatementCompatibilityHelper(statements3)) {
t.Fatalf("mismatch: %#v, %#v", expectedStatements3, statements3)
}
}

View File

@ -1,31 +0,0 @@
package plugins
import (
"fmt"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
"github.com/hashicorp/vault/sdk/helper/pluginutil"
)
// Serve is used to start a plugin's RPC server. It takes an interface that must
// implement a known plugin interface to vault and an optional api.TLSConfig for
// use during the initial unwrap request to vault. The api config is particularly
// useful when vault is setup to require client cert checking.
func Serve(plugin interface{}, tlsConfig *api.TLSConfig) {
tlsProvider := api.VaultPluginTLSProvider(tlsConfig)
err := pluginutil.OptionallyEnableMlock()
if err != nil {
fmt.Println(err)
return
}
switch p := plugin.(type) {
case dbplugin.Database:
dbplugin.Serve(p, tlsProvider)
default:
fmt.Println("Unsupported plugin type")
}
}

View File

@ -16,9 +16,9 @@ import (
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
log "github.com/hashicorp/go-hclog" log "github.com/hashicorp/go-hclog"
multierror "github.com/hashicorp/go-multierror" multierror "github.com/hashicorp/go-multierror"
"github.com/hashicorp/vault/helper/base62"
"github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/helper/namespace"
"github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/base62"
"github.com/hashicorp/vault/sdk/helper/consts" "github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/helper/jsonutil" "github.com/hashicorp/vault/sdk/helper/jsonutil"
"github.com/hashicorp/vault/sdk/helper/locksutil" "github.com/hashicorp/vault/sdk/helper/locksutil"

View File

@ -4,10 +4,10 @@ import (
"encoding/base64" "encoding/base64"
"testing" "testing"
"github.com/hashicorp/vault/helper/base62"
"github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/helper/namespace"
"github.com/hashicorp/vault/helper/pgpkeys" "github.com/hashicorp/vault/helper/pgpkeys"
"github.com/hashicorp/vault/helper/xor" "github.com/hashicorp/vault/helper/xor"
"github.com/hashicorp/vault/sdk/helper/base62"
) )
func TestCore_GenerateRoot_Lifecycle(t *testing.T) { func TestCore_GenerateRoot_Lifecycle(t *testing.T) {

View File

@ -581,7 +581,7 @@ func TestBackend_PluginMainLogical(t *testing.T) {
} }
args = append(args, fmt.Sprintf("--ca-cert=%s", caPEM)) args = append(args, fmt.Sprintf("--ca-cert=%s", caPEM))
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(args) flags.Parse(args)
tlsConfig := apiClientMeta.GetTLSConfig() tlsConfig := apiClientMeta.GetTLSConfig()
@ -610,7 +610,7 @@ func TestBackend_PluginMainCredentials(t *testing.T) {
} }
args = append(args, fmt.Sprintf("--ca-cert=%s", caPEM)) args = append(args, fmt.Sprintf("--ca-cert=%s", caPEM))
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(args) flags.Parse(args)
tlsConfig := apiClientMeta.GetTLSConfig() tlsConfig := apiClientMeta.GetTLSConfig()
@ -646,7 +646,7 @@ func TestBackend_PluginMainEnv(t *testing.T) {
} }
args = append(args, fmt.Sprintf("--ca-cert=%s", caPEM)) args = append(args, fmt.Sprintf("--ca-cert=%s", caPEM))
apiClientMeta := &api.APIClientMeta{} apiClientMeta := &api.PluginAPIClientMeta{}
flags := apiClientMeta.FlagSet() flags := apiClientMeta.FlagSet()
flags.Parse(args) flags.Parse(args)
tlsConfig := apiClientMeta.GetTLSConfig() tlsConfig := apiClientMeta.GetTLSConfig()

View File

@ -14,7 +14,7 @@ import (
multierror "github.com/hashicorp/go-multierror" multierror "github.com/hashicorp/go-multierror"
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" "github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/sdk/helper/consts" "github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/helper/jsonutil" "github.com/hashicorp/vault/sdk/helper/jsonutil"
"github.com/hashicorp/vault/sdk/helper/pluginutil" "github.com/hashicorp/vault/sdk/helper/pluginutil"

View File

@ -21,10 +21,10 @@ import (
metrics "github.com/armon/go-metrics" metrics "github.com/armon/go-metrics"
multierror "github.com/hashicorp/go-multierror" multierror "github.com/hashicorp/go-multierror"
"github.com/hashicorp/vault/helper/base62"
"github.com/hashicorp/vault/helper/identity" "github.com/hashicorp/vault/helper/identity"
"github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/helper/namespace"
"github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/base62"
"github.com/hashicorp/vault/sdk/helper/consts" "github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/helper/jsonutil" "github.com/hashicorp/vault/sdk/helper/jsonutil"
"github.com/hashicorp/vault/sdk/helper/locksutil" "github.com/hashicorp/vault/sdk/helper/locksutil"

View File

@ -129,7 +129,7 @@ import (
"os" "os"
"github.com/hashicorp/vault/sdk/helper/pluginutil" "github.com/hashicorp/vault/sdk/helper/pluginutil"
"github.com/hashicorp/vault/plugins" "github.com/hashicorp/vault/api/plugins"
) )
func main() { func main() {

View File

@ -74,7 +74,7 @@ calling the `Serve` method:
package main package main
import ( import (
"github.com/hashicorp/vault/plugins" "github.com/hashicorp/vault/api/plugins"
) )
func main() { func main() {