mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 02:28:09 +00:00 
			
		
		
		
	DBPW - Copy newdbplugin package to dbplugin/v5 (#10151)
				
					
				
			This is part 1 of 4 for renaming the `newdbplugin` package. This copies the existing package to the new location but keeps the current one in place so we can migrate the existing references over more easily.
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -200,7 +200,7 @@ proto: | |||||||
| 	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 sdk/database/dbplugin/*.proto --go_out=plugins=grpc,paths=source_relative:. | 	protoc sdk/database/dbplugin/*.proto --go_out=plugins=grpc,paths=source_relative:. | ||||||
| 	protoc sdk/database/newdbplugin/proto/*.proto --go_out=plugins=grpc,paths=source_relative:. | 	protoc sdk/database/dbplugin/v5/proto/*.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/Id/ID/' vault/request_forwarding_service.pb.go | 	sed -i -e 's/Id/ID/' vault/request_forwarding_service.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 vault/activity/activity_log.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 vault/activity/activity_log.pb.go | ||||||
|   | |||||||
| @@ -11,9 +11,9 @@ import ( | |||||||
| 	"github.com/hashicorp/errwrap" | 	"github.com/hashicorp/errwrap" | ||||||
| 	log "github.com/hashicorp/go-hclog" | 	log "github.com/hashicorp/go-hclog" | ||||||
| 	"github.com/hashicorp/go-uuid" | 	"github.com/hashicorp/go-uuid" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/dbplugin" | 	v4 "github.com/hashicorp/vault/sdk/database/dbplugin" | ||||||
|  | 	v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" |  | ||||||
| 	"github.com/hashicorp/vault/sdk/framework" | 	"github.com/hashicorp/vault/sdk/framework" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/locksutil" | 	"github.com/hashicorp/vault/sdk/helper/locksutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/strutil" | 	"github.com/hashicorp/vault/sdk/helper/strutil" | ||||||
| @@ -193,7 +193,7 @@ func (b *databaseBackend) roleAtPath(ctx context.Context, s logical.Storage, rol | |||||||
|  |  | ||||||
| 	switch { | 	switch { | ||||||
| 	case upgradeCh.Statements != nil: | 	case upgradeCh.Statements != nil: | ||||||
| 		var stmts dbplugin.Statements | 		var stmts v4.Statements | ||||||
| 		if upgradeCh.Statements.CreationStatements != "" { | 		if upgradeCh.Statements.CreationStatements != "" { | ||||||
| 			stmts.Creation = []string{upgradeCh.Statements.CreationStatements} | 			stmts.Creation = []string{upgradeCh.Statements.CreationStatements} | ||||||
| 		} | 		} | ||||||
| @@ -265,7 +265,7 @@ func (b *databaseBackend) GetConnectionWithConfig(ctx context.Context, name stri | |||||||
| 		return nil, fmt.Errorf("unable to create database instance: %w", err) | 		return nil, fmt.Errorf("unable to create database instance: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	initReq := newdbplugin.InitializeRequest{ | 	initReq := v5.InitializeRequest{ | ||||||
| 		Config:           config.ConnectionDetails, | 		Config:           config.ConnectionDetails, | ||||||
| 		VerifyConnection: true, | 		VerifyConnection: true, | ||||||
| 	} | 	} | ||||||
| @@ -316,7 +316,7 @@ func (b *databaseBackend) clearConnection(name string) error { | |||||||
| func (b *databaseBackend) CloseIfShutdown(db *dbPluginInstance, err error) { | func (b *databaseBackend) CloseIfShutdown(db *dbPluginInstance, err error) { | ||||||
| 	// Plugin has shutdown, close it so next call can reconnect. | 	// Plugin has shutdown, close it so next call can reconnect. | ||||||
| 	switch err { | 	switch err { | ||||||
| 	case rpc.ErrShutdown, dbplugin.ErrPluginShutdown: | 	case rpc.ErrShutdown, v4.ErrPluginShutdown: | ||||||
| 		// Put this in a goroutine so that requests can run with the read or write lock | 		// Put this in a goroutine so that requests can run with the read or write lock | ||||||
| 		// and simply defer the unlock.  Since we are attaching the instance and matching | 		// and simply defer the unlock.  Since we are attaching the instance and matching | ||||||
| 		// the id in the connection map, we can safely do this. | 		// the id in the connection map, we can safely do this. | ||||||
|   | |||||||
| @@ -4,35 +4,35 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/sdk/database/dbplugin" | 	v4 "github.com/hashicorp/vault/sdk/database/dbplugin" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/stretchr/testify/mock" | 	"github.com/stretchr/testify/mock" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var _ newdbplugin.Database = &mockNewDatabase{} | var _ v5.Database = &mockNewDatabase{} | ||||||
|  |  | ||||||
| type mockNewDatabase struct { | type mockNewDatabase struct { | ||||||
| 	mock.Mock | 	mock.Mock | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *mockNewDatabase) Initialize(ctx context.Context, req newdbplugin.InitializeRequest) (newdbplugin.InitializeResponse, error) { | func (m *mockNewDatabase) Initialize(ctx context.Context, req v5.InitializeRequest) (v5.InitializeResponse, error) { | ||||||
| 	args := m.Called(ctx, req) | 	args := m.Called(ctx, req) | ||||||
| 	return args.Get(0).(newdbplugin.InitializeResponse), args.Error(1) | 	return args.Get(0).(v5.InitializeResponse), args.Error(1) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *mockNewDatabase) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) (newdbplugin.NewUserResponse, error) { | func (m *mockNewDatabase) NewUser(ctx context.Context, req v5.NewUserRequest) (v5.NewUserResponse, error) { | ||||||
| 	args := m.Called(ctx, req) | 	args := m.Called(ctx, req) | ||||||
| 	return args.Get(0).(newdbplugin.NewUserResponse), args.Error(1) | 	return args.Get(0).(v5.NewUserResponse), args.Error(1) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *mockNewDatabase) UpdateUser(ctx context.Context, req newdbplugin.UpdateUserRequest) (newdbplugin.UpdateUserResponse, error) { | func (m *mockNewDatabase) UpdateUser(ctx context.Context, req v5.UpdateUserRequest) (v5.UpdateUserResponse, error) { | ||||||
| 	args := m.Called(ctx, req) | 	args := m.Called(ctx, req) | ||||||
| 	return args.Get(0).(newdbplugin.UpdateUserResponse), args.Error(1) | 	return args.Get(0).(v5.UpdateUserResponse), args.Error(1) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *mockNewDatabase) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserRequest) (newdbplugin.DeleteUserResponse, error) { | func (m *mockNewDatabase) DeleteUser(ctx context.Context, req v5.DeleteUserRequest) (v5.DeleteUserResponse, error) { | ||||||
| 	args := m.Called(ctx, req) | 	args := m.Called(ctx, req) | ||||||
| 	return args.Get(0).(newdbplugin.DeleteUserResponse), args.Error(1) | 	return args.Get(0).(v5.DeleteUserResponse), args.Error(1) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *mockNewDatabase) Type() (string, error) { | func (m *mockNewDatabase) Type() (string, error) { | ||||||
| @@ -45,23 +45,23 @@ func (m *mockNewDatabase) Close() error { | |||||||
| 	return args.Error(0) | 	return args.Error(0) | ||||||
| } | } | ||||||
|  |  | ||||||
| var _ dbplugin.Database = &mockLegacyDatabase{} | var _ v4.Database = &mockLegacyDatabase{} | ||||||
|  |  | ||||||
| type mockLegacyDatabase struct { | type mockLegacyDatabase struct { | ||||||
| 	mock.Mock | 	mock.Mock | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *mockLegacyDatabase) CreateUser(ctx context.Context, statements dbplugin.Statements, usernameConfig dbplugin.UsernameConfig, expiration time.Time) (username string, password string, err error) { | func (m *mockLegacyDatabase) CreateUser(ctx context.Context, statements v4.Statements, usernameConfig v4.UsernameConfig, expiration time.Time) (username string, password string, err error) { | ||||||
| 	args := m.Called(ctx, statements, usernameConfig, expiration) | 	args := m.Called(ctx, statements, usernameConfig, expiration) | ||||||
| 	return args.String(0), args.String(1), args.Error(2) | 	return args.String(0), args.String(1), args.Error(2) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *mockLegacyDatabase) RenewUser(ctx context.Context, statements dbplugin.Statements, username string, expiration time.Time) error { | func (m *mockLegacyDatabase) RenewUser(ctx context.Context, statements v4.Statements, username string, expiration time.Time) error { | ||||||
| 	args := m.Called(ctx, statements, username, expiration) | 	args := m.Called(ctx, statements, username, expiration) | ||||||
| 	return args.Error(0) | 	return args.Error(0) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *mockLegacyDatabase) RevokeUser(ctx context.Context, statements dbplugin.Statements, username string) error { | func (m *mockLegacyDatabase) RevokeUser(ctx context.Context, statements v4.Statements, username string) error { | ||||||
| 	args := m.Called(ctx, statements, username) | 	args := m.Called(ctx, statements, username) | ||||||
| 	return args.Error(0) | 	return args.Error(0) | ||||||
| } | } | ||||||
| @@ -76,7 +76,7 @@ func (m *mockLegacyDatabase) GenerateCredentials(ctx context.Context) (string, e | |||||||
| 	return args.String(0), args.Error(1) | 	return args.String(0), args.Error(1) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *mockLegacyDatabase) SetCredentials(ctx context.Context, statements dbplugin.Statements, staticConfig dbplugin.StaticUserConfig) (username string, password string, err error) { | func (m *mockLegacyDatabase) SetCredentials(ctx context.Context, statements v4.Statements, staticConfig v4.StaticUserConfig) (username string, password string, err error) { | ||||||
| 	args := m.Called(ctx, statements, staticConfig) | 	args := m.Called(ctx, statements, staticConfig) | ||||||
| 	return args.String(0), args.String(1), args.Error(2) | 	return args.String(0), args.String(1), args.Error(2) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ 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/sdk/database/dbplugin" | 	v4 "github.com/hashicorp/vault/sdk/database/dbplugin" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const mockV4Type = "mockv4" | const mockV4Type = "mockv4" | ||||||
| @@ -17,7 +17,7 @@ type MockDatabaseV4 struct { | |||||||
| 	config map[string]interface{} | 	config map[string]interface{} | ||||||
| } | } | ||||||
|  |  | ||||||
| var _ dbplugin.Database = &MockDatabaseV4{} | var _ v4.Database = &MockDatabaseV4{} | ||||||
|  |  | ||||||
| // New returns a new in-memory instance | // New returns a new in-memory instance | ||||||
| func NewV4() (interface{}, error) { | func NewV4() (interface{}, error) { | ||||||
| @@ -31,7 +31,7 @@ func RunV4(apiTLSConfig *api.TLSConfig) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | 	v4.Serve(dbType.(v4.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -49,7 +49,7 @@ func (m MockDatabaseV4) Initialize(ctx context.Context, config map[string]interf | |||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m MockDatabaseV4) CreateUser(ctx context.Context, statements dbplugin.Statements, usernameConfig dbplugin.UsernameConfig, expiration time.Time) (username string, password string, err error) { | func (m MockDatabaseV4) CreateUser(ctx context.Context, statements v4.Statements, usernameConfig v4.UsernameConfig, expiration time.Time) (username string, password string, err error) { | ||||||
| 	log.Default().Info("CreateUser called", | 	log.Default().Info("CreateUser called", | ||||||
| 		"statements", statements, | 		"statements", statements, | ||||||
| 		"usernameConfig", usernameConfig, | 		"usernameConfig", usernameConfig, | ||||||
| @@ -64,7 +64,7 @@ func (m MockDatabaseV4) CreateUser(ctx context.Context, statements dbplugin.Stat | |||||||
| 	return user, pass, nil | 	return user, pass, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m MockDatabaseV4) RenewUser(ctx context.Context, statements dbplugin.Statements, username string, expiration time.Time) error { | func (m MockDatabaseV4) RenewUser(ctx context.Context, statements v4.Statements, username string, expiration time.Time) error { | ||||||
| 	log.Default().Info("RenewUser called", | 	log.Default().Info("RenewUser called", | ||||||
| 		"statements", statements, | 		"statements", statements, | ||||||
| 		"username", username, | 		"username", username, | ||||||
| @@ -73,7 +73,7 @@ func (m MockDatabaseV4) RenewUser(ctx context.Context, statements dbplugin.State | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m MockDatabaseV4) RevokeUser(ctx context.Context, statements dbplugin.Statements, username string) error { | func (m MockDatabaseV4) RevokeUser(ctx context.Context, statements v4.Statements, username string) error { | ||||||
| 	log.Default().Info("RevokeUser called", | 	log.Default().Info("RevokeUser called", | ||||||
| 		"statements", statements, | 		"statements", statements, | ||||||
| 		"username", username) | 		"username", username) | ||||||
| @@ -94,7 +94,7 @@ func (m MockDatabaseV4) RotateRootCredentials(ctx context.Context, statements [] | |||||||
| 	return m.config, nil | 	return m.config, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m MockDatabaseV4) SetCredentials(ctx context.Context, statements dbplugin.Statements, staticConfig dbplugin.StaticUserConfig) (username string, password string, err error) { | func (m MockDatabaseV4) SetCredentials(ctx context.Context, statements v4.Statements, staticConfig v4.StaticUserConfig) (username string, password string, err error) { | ||||||
| 	log.Default().Info("SetCredentials called", | 	log.Default().Info("SetCredentials called", | ||||||
| 		"statements", statements, | 		"statements", statements, | ||||||
| 		"staticConfig", staticConfig) | 		"staticConfig", staticConfig) | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ 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/sdk/database/newdbplugin" | 	v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const mockV5Type = "mockv5" | const mockV5Type = "mockv5" | ||||||
| @@ -17,7 +17,7 @@ type MockDatabaseV5 struct { | |||||||
| 	config map[string]interface{} | 	config map[string]interface{} | ||||||
| } | } | ||||||
|  |  | ||||||
| var _ newdbplugin.Database = &MockDatabaseV5{} | var _ v5.Database = &MockDatabaseV5{} | ||||||
|  |  | ||||||
| // New returns a new in-memory instance | // New returns a new in-memory instance | ||||||
| func New() (interface{}, error) { | func New() (interface{}, error) { | ||||||
| @@ -32,46 +32,46 @@ func RunV5(apiTLSConfig *api.TLSConfig) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	newdbplugin.Serve(dbType.(newdbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | 	v5.Serve(dbType.(v5.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m MockDatabaseV5) Initialize(ctx context.Context, req newdbplugin.InitializeRequest) (newdbplugin.InitializeResponse, error) { | func (m MockDatabaseV5) Initialize(ctx context.Context, req v5.InitializeRequest) (v5.InitializeResponse, error) { | ||||||
| 	log.Default().Info("Initialize called", | 	log.Default().Info("Initialize called", | ||||||
| 		"req", req) | 		"req", req) | ||||||
|  |  | ||||||
| 	config := req.Config | 	config := req.Config | ||||||
| 	config["from-plugin"] = "this value is from the plugin itself" | 	config["from-plugin"] = "this value is from the plugin itself" | ||||||
|  |  | ||||||
| 	resp := newdbplugin.InitializeResponse{ | 	resp := v5.InitializeResponse{ | ||||||
| 		Config: req.Config, | 		Config: req.Config, | ||||||
| 	} | 	} | ||||||
| 	return resp, nil | 	return resp, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m MockDatabaseV5) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) (newdbplugin.NewUserResponse, error) { | func (m MockDatabaseV5) NewUser(ctx context.Context, req v5.NewUserRequest) (v5.NewUserResponse, error) { | ||||||
| 	log.Default().Info("NewUser called", | 	log.Default().Info("NewUser called", | ||||||
| 		"req", req) | 		"req", req) | ||||||
|  |  | ||||||
| 	now := time.Now() | 	now := time.Now() | ||||||
| 	user := fmt.Sprintf("mockv5_user_%s", now.Format(time.RFC3339)) | 	user := fmt.Sprintf("mockv5_user_%s", now.Format(time.RFC3339)) | ||||||
| 	resp := newdbplugin.NewUserResponse{ | 	resp := v5.NewUserResponse{ | ||||||
| 		Username: user, | 		Username: user, | ||||||
| 	} | 	} | ||||||
| 	return resp, nil | 	return resp, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m MockDatabaseV5) UpdateUser(ctx context.Context, req newdbplugin.UpdateUserRequest) (newdbplugin.UpdateUserResponse, error) { | func (m MockDatabaseV5) UpdateUser(ctx context.Context, req v5.UpdateUserRequest) (v5.UpdateUserResponse, error) { | ||||||
| 	log.Default().Info("UpdateUser called", | 	log.Default().Info("UpdateUser called", | ||||||
| 		"req", req) | 		"req", req) | ||||||
| 	return newdbplugin.UpdateUserResponse{}, nil | 	return v5.UpdateUserResponse{}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m MockDatabaseV5) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserRequest) (newdbplugin.DeleteUserResponse, error) { | func (m MockDatabaseV5) DeleteUser(ctx context.Context, req v5.DeleteUserRequest) (v5.DeleteUserResponse, error) { | ||||||
| 	log.Default().Info("DeleteUser called", | 	log.Default().Info("DeleteUser called", | ||||||
| 		"req", req) | 		"req", req) | ||||||
| 	return newdbplugin.DeleteUserResponse{}, nil | 	return v5.DeleteUserResponse{}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m MockDatabaseV5) Type() (string, error) { | func (m MockDatabaseV5) Type() (string, error) { | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ import ( | |||||||
| 	"github.com/fatih/structs" | 	"github.com/fatih/structs" | ||||||
| 	"github.com/hashicorp/errwrap" | 	"github.com/hashicorp/errwrap" | ||||||
| 	uuid "github.com/hashicorp/go-uuid" | 	uuid "github.com/hashicorp/go-uuid" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/framework" | 	"github.com/hashicorp/vault/sdk/framework" | ||||||
| 	"github.com/hashicorp/vault/sdk/logical" | 	"github.com/hashicorp/vault/sdk/logical" | ||||||
| ) | ) | ||||||
| @@ -318,7 +318,7 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc { | |||||||
| 			return logical.ErrorResponse("error creating database object: %s", err), nil | 			return logical.ErrorResponse("error creating database object: %s", err), nil | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		initReq := newdbplugin.InitializeRequest{ | 		initReq := v5.InitializeRequest{ | ||||||
| 			Config:           config.ConnectionDetails, | 			Config:           config.ConnectionDetails, | ||||||
| 			VerifyConnection: verifyConnection, | 			VerifyConnection: verifyConnection, | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"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" | ||||||
| @@ -95,15 +95,15 @@ func (b *databaseBackend) pathCredsCreateRead() framework.OperationFunc { | |||||||
| 			return nil, fmt.Errorf("unable to generate password: %w", err) | 			return nil, fmt.Errorf("unable to generate password: %w", err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		newUserReq := newdbplugin.NewUserRequest{ | 		newUserReq := v5.NewUserRequest{ | ||||||
| 			UsernameConfig: newdbplugin.UsernameMetadata{ | 			UsernameConfig: v5.UsernameMetadata{ | ||||||
| 				DisplayName: req.DisplayName, | 				DisplayName: req.DisplayName, | ||||||
| 				RoleName:    name, | 				RoleName:    name, | ||||||
| 			}, | 			}, | ||||||
| 			Statements: newdbplugin.Statements{ | 			Statements: v5.Statements{ | ||||||
| 				Commands: role.Statements.Creation, | 				Commands: role.Statements.Creation, | ||||||
| 			}, | 			}, | ||||||
| 			RollbackStatements: newdbplugin.Statements{ | 			RollbackStatements: v5.Statements{ | ||||||
| 				Commands: role.Statements.Rollback, | 				Commands: role.Statements.Rollback, | ||||||
| 			}, | 			}, | ||||||
| 			Password:   password, | 			Password:   password, | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/sdk/database/dbplugin" | 	v4 "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/locksutil" | 	"github.com/hashicorp/vault/sdk/helper/locksutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/strutil" | 	"github.com/hashicorp/vault/sdk/helper/strutil" | ||||||
| @@ -523,7 +523,7 @@ func (b *databaseBackend) pathStaticRoleCreateUpdate(ctx context.Context, req *l | |||||||
|  |  | ||||||
| type roleEntry struct { | type roleEntry struct { | ||||||
| 	DBName        string         `json:"db_name"` | 	DBName        string         `json:"db_name"` | ||||||
| 	Statements    dbplugin.Statements `json:"statements"` | 	Statements    v4.Statements  `json:"statements"` | ||||||
| 	DefaultTTL    time.Duration  `json:"default_ttl"` | 	DefaultTTL    time.Duration  `json:"default_ttl"` | ||||||
| 	MaxTTL        time.Duration  `json:"max_ttl"` | 	MaxTTL        time.Duration  `json:"max_ttl"` | ||||||
| 	StaticAccount *staticAccount `json:"static_account" mapstructure:"static_account"` | 	StaticAccount *staticAccount `json:"static_account" mapstructure:"static_account"` | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/framework" | 	"github.com/hashicorp/vault/sdk/framework" | ||||||
| 	"github.com/hashicorp/vault/sdk/logical" | 	"github.com/hashicorp/vault/sdk/logical" | ||||||
| 	"github.com/hashicorp/vault/sdk/queue" | 	"github.com/hashicorp/vault/sdk/queue" | ||||||
| @@ -111,11 +111,11 @@ func (b *databaseBackend) pathRotateRootCredentialsUpdate() framework.OperationF | |||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		updateReq := newdbplugin.UpdateUserRequest{ | 		updateReq := v5.UpdateUserRequest{ | ||||||
| 			Username: username, | 			Username: username, | ||||||
| 			Password: &newdbplugin.ChangePassword{ | 			Password: &v5.ChangePassword{ | ||||||
| 				NewPassword: newPassword, | 				NewPassword: newPassword, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: v5.Statements{ | ||||||
| 					Commands: config.RootCredentialsRotateStatements, | 					Commands: config.RootCredentialsRotateStatements, | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
| 	"errors" | 	"errors" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/logical" | 	"github.com/hashicorp/vault/sdk/logical" | ||||||
| 	"github.com/mitchellh/mapstructure" | 	"github.com/mitchellh/mapstructure" | ||||||
| 	"google.golang.org/grpc/codes" | 	"google.golang.org/grpc/codes" | ||||||
| @@ -91,11 +91,11 @@ func (b *databaseBackend) rollbackDatabaseCredentials(ctx context.Context, confi | |||||||
| 		} | 		} | ||||||
| 	}() | 	}() | ||||||
|  |  | ||||||
| 	updateReq := newdbplugin.UpdateUserRequest{ | 	updateReq := v5.UpdateUserRequest{ | ||||||
| 		Username: entry.UserName, | 		Username: entry.UserName, | ||||||
| 		Password: &newdbplugin.ChangePassword{ | 		Password: &v5.ChangePassword{ | ||||||
| 			NewPassword: entry.OldPassword, | 			NewPassword: entry.OldPassword, | ||||||
| 			Statements: newdbplugin.Statements{ | 			Statements: v5.Statements{ | ||||||
| 				Commands: config.RootCredentialsRotateStatements, | 				Commands: config.RootCredentialsRotateStatements, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/helper/namespace" | 	"github.com/hashicorp/vault/helper/namespace" | ||||||
| 	postgreshelper "github.com/hashicorp/vault/helper/testhelpers/postgresql" | 	postgreshelper "github.com/hashicorp/vault/helper/testhelpers/postgresql" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/framework" | 	"github.com/hashicorp/vault/sdk/framework" | ||||||
| 	"github.com/hashicorp/vault/sdk/logical" | 	"github.com/hashicorp/vault/sdk/logical" | ||||||
| ) | ) | ||||||
| @@ -102,9 +102,9 @@ func TestBackend_RotateRootCredentials_WAL_rollback(t *testing.T) { | |||||||
| 	// Alter the database password so it no longer matches what is in storage | 	// Alter the database password so it no longer matches what is in storage | ||||||
| 	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) | 	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) | ||||||
| 	defer cancel() | 	defer cancel() | ||||||
| 	updateReq := newdbplugin.UpdateUserRequest{ | 	updateReq := v5.UpdateUserRequest{ | ||||||
| 		Username: databaseUser, | 		Username: databaseUser, | ||||||
| 		Password: &newdbplugin.ChangePassword{ | 		Password: &v5.ChangePassword{ | ||||||
| 			NewPassword: "newSecret", | 			NewPassword: "newSecret", | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| @@ -348,9 +348,9 @@ func TestBackend_RotateRootCredentials_WAL_no_rollback_2(t *testing.T) { | |||||||
| 	// Alter the database password | 	// Alter the database password | ||||||
| 	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) | 	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) | ||||||
| 	defer cancel() | 	defer cancel() | ||||||
| 	updateReq := newdbplugin.UpdateUserRequest{ | 	updateReq := v5.UpdateUserRequest{ | ||||||
| 		Username: databaseUser, | 		Username: databaseUser, | ||||||
| 		Password: &newdbplugin.ChangePassword{ | 		Password: &v5.ChangePassword{ | ||||||
| 			NewPassword: "newSecret", | 			NewPassword: "newSecret", | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -9,8 +9,8 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/hashicorp/errwrap" | 	"github.com/hashicorp/errwrap" | ||||||
| 	"github.com/hashicorp/go-multierror" | 	"github.com/hashicorp/go-multierror" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/dbplugin" | 	v4 "github.com/hashicorp/vault/sdk/database/dbplugin" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"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/locksutil" | 	"github.com/hashicorp/vault/sdk/helper/locksutil" | ||||||
| @@ -340,7 +340,7 @@ func (b *databaseBackend) setStaticAccount(ctx context.Context, s logical.Storag | |||||||
| 	} | 	} | ||||||
| 	output.Password = newPassword | 	output.Password = newPassword | ||||||
|  |  | ||||||
| 	config := dbplugin.StaticUserConfig{ | 	config := v4.StaticUserConfig{ | ||||||
| 		Username: input.Role.StaticAccount.Username, | 		Username: input.Role.StaticAccount.Username, | ||||||
| 		Password: newPassword, | 		Password: newPassword, | ||||||
| 	} | 	} | ||||||
| @@ -358,11 +358,11 @@ func (b *databaseBackend) setStaticAccount(ctx context.Context, s logical.Storag | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	updateReq := newdbplugin.UpdateUserRequest{ | 	updateReq := v5.UpdateUserRequest{ | ||||||
| 		Username: input.Role.StaticAccount.Username, | 		Username: input.Role.StaticAccount.Username, | ||||||
| 		Password: &newdbplugin.ChangePassword{ | 		Password: &v5.ChangePassword{ | ||||||
| 			NewPassword: newPassword, | 			NewPassword: newPassword, | ||||||
| 			Statements: newdbplugin.Statements{ | 			Statements: v5.Statements{ | ||||||
| 				Commands: input.Role.Statements.Rotation, | 				Commands: input.Role.Statements.Rotation, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
|   | |||||||
| @@ -2,14 +2,13 @@ package database | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"database/sql" | ||||||
| 	"log" | 	"log" | ||||||
| 	"os" | 	"os" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"database/sql" |  | ||||||
|  |  | ||||||
| 	"github.com/Sectorbob/mlab-ns2/gae/ns/digest" | 	"github.com/Sectorbob/mlab-ns2/gae/ns/digest" | ||||||
| 	"github.com/hashicorp/vault/helper/namespace" | 	"github.com/hashicorp/vault/helper/namespace" | ||||||
| 	"github.com/hashicorp/vault/helper/testhelpers/mongodb" | 	"github.com/hashicorp/vault/helper/testhelpers/mongodb" | ||||||
|   | |||||||
| @@ -5,8 +5,8 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/sdk/database/dbplugin" | 	v4 "github.com/hashicorp/vault/sdk/database/dbplugin" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/framework" | 	"github.com/hashicorp/vault/sdk/framework" | ||||||
| 	"github.com/hashicorp/vault/sdk/logical" | 	"github.com/hashicorp/vault/sdk/logical" | ||||||
| ) | ) | ||||||
| @@ -65,11 +65,11 @@ func (b *databaseBackend) secretCredsRenew() framework.OperationFunc { | |||||||
| 			// to ensure the database credential does not expire before the lease | 			// to ensure the database credential does not expire before the lease | ||||||
| 			expireTime = expireTime.Add(5 * time.Second) | 			expireTime = expireTime.Add(5 * time.Second) | ||||||
|  |  | ||||||
| 			updateReq := newdbplugin.UpdateUserRequest{ | 			updateReq := v5.UpdateUserRequest{ | ||||||
| 				Username: username, | 				Username: username, | ||||||
| 				Expiration: &newdbplugin.ChangeExpiration{ | 				Expiration: &v5.ChangeExpiration{ | ||||||
| 					NewExpiration: expireTime, | 					NewExpiration: expireTime, | ||||||
| 					Statements: newdbplugin.Statements{ | 					Statements: v5.Statements{ | ||||||
| 						Commands: role.Statements.Renewal, | 						Commands: role.Statements.Renewal, | ||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
| @@ -104,7 +104,7 @@ func (b *databaseBackend) secretCredsRevoke() framework.OperationFunc { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		var dbName string | 		var dbName string | ||||||
| 		var statements dbplugin.Statements | 		var statements v4.Statements | ||||||
|  |  | ||||||
| 		role, err := b.Role(ctx, req.Storage, roleNameRaw.(string)) | 		role, err := b.Role(ctx, req.Storage, roleNameRaw.(string)) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| @@ -148,9 +148,9 @@ func (b *databaseBackend) secretCredsRevoke() framework.OperationFunc { | |||||||
| 		dbi.RLock() | 		dbi.RLock() | ||||||
| 		defer dbi.RUnlock() | 		defer dbi.RUnlock() | ||||||
|  |  | ||||||
| 		deleteReq := newdbplugin.DeleteUserRequest{ | 		deleteReq := v5.DeleteUserRequest{ | ||||||
| 			Username: username, | 			Username: username, | ||||||
| 			Statements: newdbplugin.Statements{ | 			Statements: v5.Statements{ | ||||||
| 				Commands: statements.Revocation, | 				Commands: statements.Revocation, | ||||||
| 			}, | 			}, | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -8,22 +8,22 @@ import ( | |||||||
| 	log "github.com/hashicorp/go-hclog" | 	log "github.com/hashicorp/go-hclog" | ||||||
| 	"github.com/hashicorp/go-multierror" | 	"github.com/hashicorp/go-multierror" | ||||||
| 	"github.com/hashicorp/vault/helper/random" | 	"github.com/hashicorp/vault/helper/random" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/dbplugin" | 	v4 "github.com/hashicorp/vault/sdk/database/dbplugin" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/pluginutil" | 	"github.com/hashicorp/vault/sdk/helper/pluginutil" | ||||||
| 	"google.golang.org/grpc/codes" | 	"google.golang.org/grpc/codes" | ||||||
| 	"google.golang.org/grpc/status" | 	"google.golang.org/grpc/status" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type databaseVersionWrapper struct { | type databaseVersionWrapper struct { | ||||||
| 	v4 dbplugin.Database | 	v4 v4.Database | ||||||
| 	v5 newdbplugin.Database | 	v5 v5.Database | ||||||
| } | } | ||||||
|  |  | ||||||
| // newDatabaseWrapper figures out which version of the database the pluginName is referring to and returns a wrapper object | // newDatabaseWrapper figures out which version of the database the pluginName is referring to and returns a wrapper object | ||||||
| // that can be used to make operations on the underlying database plugin. | // that can be used to make operations on the underlying database plugin. | ||||||
| func newDatabaseWrapper(ctx context.Context, pluginName string, sys pluginutil.LookRunnerUtil, logger log.Logger) (dbw databaseVersionWrapper, err error) { | func newDatabaseWrapper(ctx context.Context, pluginName string, sys pluginutil.LookRunnerUtil, logger log.Logger) (dbw databaseVersionWrapper, err error) { | ||||||
| 	newDB, err := newdbplugin.PluginFactory(ctx, pluginName, sys, logger) | 	newDB, err := v5.PluginFactory(ctx, pluginName, sys, logger) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		dbw = databaseVersionWrapper{ | 		dbw = databaseVersionWrapper{ | ||||||
| 			v5: newDB, | 			v5: newDB, | ||||||
| @@ -34,7 +34,7 @@ func newDatabaseWrapper(ctx context.Context, pluginName string, sys pluginutil.L | |||||||
| 	merr := &multierror.Error{} | 	merr := &multierror.Error{} | ||||||
| 	merr = multierror.Append(merr, err) | 	merr = multierror.Append(merr, err) | ||||||
|  |  | ||||||
| 	legacyDB, err := dbplugin.PluginFactory(ctx, pluginName, sys, logger) | 	legacyDB, err := v4.PluginFactory(ctx, pluginName, sys, logger) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		dbw = databaseVersionWrapper{ | 		dbw = databaseVersionWrapper{ | ||||||
| 			v4: legacyDB, | 			v4: legacyDB, | ||||||
| @@ -48,9 +48,9 @@ func newDatabaseWrapper(ctx context.Context, pluginName string, sys pluginutil.L | |||||||
|  |  | ||||||
| // Initialize the underlying database. This is analogous to a constructor on the database plugin object. | // Initialize the underlying database. This is analogous to a constructor on the database plugin object. | ||||||
| // Errors if the wrapper does not contain an underlying database. | // Errors if the wrapper does not contain an underlying database. | ||||||
| func (d databaseVersionWrapper) Initialize(ctx context.Context, req newdbplugin.InitializeRequest) (newdbplugin.InitializeResponse, error) { | func (d databaseVersionWrapper) Initialize(ctx context.Context, req v5.InitializeRequest) (v5.InitializeResponse, error) { | ||||||
| 	if !d.isV5() && !d.isV4() { | 	if !d.isV5() && !d.isV4() { | ||||||
| 		return newdbplugin.InitializeResponse{}, fmt.Errorf("no underlying database specified") | 		return v5.InitializeResponse{}, fmt.Errorf("no underlying database specified") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// v5 Database | 	// v5 Database | ||||||
| @@ -61,9 +61,9 @@ func (d databaseVersionWrapper) Initialize(ctx context.Context, req newdbplugin. | |||||||
| 	// v4 Database | 	// v4 Database | ||||||
| 	saveConfig, err := d.v4.Init(ctx, req.Config, req.VerifyConnection) | 	saveConfig, err := d.v4.Init(ctx, req.Config, req.VerifyConnection) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.InitializeResponse{}, err | 		return v5.InitializeResponse{}, err | ||||||
| 	} | 	} | ||||||
| 	resp := newdbplugin.InitializeResponse{ | 	resp := v5.InitializeResponse{ | ||||||
| 		Config: saveConfig, | 		Config: saveConfig, | ||||||
| 	} | 	} | ||||||
| 	return resp, nil | 	return resp, nil | ||||||
| @@ -74,9 +74,9 @@ func (d databaseVersionWrapper) Initialize(ctx context.Context, req newdbplugin. | |||||||
| // does not have a way of returning the password so this function signature needs to be different. | // does not have a way of returning the password so this function signature needs to be different. | ||||||
| // The password returned here should be considered the source of truth, not the provided password. | // The password returned here should be considered the source of truth, not the provided password. | ||||||
| // Errors if the wrapper does not contain an underlying database. | // Errors if the wrapper does not contain an underlying database. | ||||||
| func (d databaseVersionWrapper) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) (resp newdbplugin.NewUserResponse, password string, err error) { | func (d databaseVersionWrapper) NewUser(ctx context.Context, req v5.NewUserRequest) (resp v5.NewUserResponse, password string, err error) { | ||||||
| 	if !d.isV5() && !d.isV4() { | 	if !d.isV5() && !d.isV4() { | ||||||
| 		return newdbplugin.NewUserResponse{}, "", fmt.Errorf("no underlying database specified") | 		return v5.NewUserResponse{}, "", fmt.Errorf("no underlying database specified") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// v5 Database | 	// v5 Database | ||||||
| @@ -86,11 +86,11 @@ func (d databaseVersionWrapper) NewUser(ctx context.Context, req newdbplugin.New | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// v4 Database | 	// v4 Database | ||||||
| 	stmts := dbplugin.Statements{ | 	stmts := v4.Statements{ | ||||||
| 		Creation: req.Statements.Commands, | 		Creation: req.Statements.Commands, | ||||||
| 		Rollback: req.RollbackStatements.Commands, | 		Rollback: req.RollbackStatements.Commands, | ||||||
| 	} | 	} | ||||||
| 	usernameConfig := dbplugin.UsernameConfig{ | 	usernameConfig := v4.UsernameConfig{ | ||||||
| 		DisplayName: req.UsernameConfig.DisplayName, | 		DisplayName: req.UsernameConfig.DisplayName, | ||||||
| 		RoleName:    req.UsernameConfig.RoleName, | 		RoleName:    req.UsernameConfig.RoleName, | ||||||
| 	} | 	} | ||||||
| @@ -99,7 +99,7 @@ func (d databaseVersionWrapper) NewUser(ctx context.Context, req newdbplugin.New | |||||||
| 		return resp, "", err | 		return resp, "", err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	resp = newdbplugin.NewUserResponse{ | 	resp = v5.NewUserResponse{ | ||||||
| 		Username: username, | 		Username: username, | ||||||
| 	} | 	} | ||||||
| 	return resp, password, nil | 	return resp, password, nil | ||||||
| @@ -108,7 +108,7 @@ func (d databaseVersionWrapper) NewUser(ctx context.Context, req newdbplugin.New | |||||||
| // UpdateUser in the underlying database. This is used to update any information currently supported | // UpdateUser in the underlying database. This is used to update any information currently supported | ||||||
| // in the UpdateUserRequest such as password credentials or user TTL. | // in the UpdateUserRequest such as password credentials or user TTL. | ||||||
| // Errors if the wrapper does not contain an underlying database. | // Errors if the wrapper does not contain an underlying database. | ||||||
| func (d databaseVersionWrapper) UpdateUser(ctx context.Context, req newdbplugin.UpdateUserRequest, isRootUser bool) (saveConfig map[string]interface{}, err error) { | func (d databaseVersionWrapper) UpdateUser(ctx context.Context, req v5.UpdateUserRequest, isRootUser bool) (saveConfig map[string]interface{}, err error) { | ||||||
| 	if !d.isV5() && !d.isV4() { | 	if !d.isV5() && !d.isV4() { | ||||||
| 		return nil, fmt.Errorf("no underlying database specified") | 		return nil, fmt.Errorf("no underlying database specified") | ||||||
| 	} | 	} | ||||||
| @@ -136,7 +136,7 @@ func (d databaseVersionWrapper) UpdateUser(ctx context.Context, req newdbplugin. | |||||||
|  |  | ||||||
| 	// Change expiration date | 	// Change expiration date | ||||||
| 	if req.Expiration != nil { | 	if req.Expiration != nil { | ||||||
| 		stmts := dbplugin.Statements{ | 		stmts := v4.Statements{ | ||||||
| 			Renewal: req.Expiration.Statements.Commands, | 			Renewal: req.Expiration.Statements.Commands, | ||||||
| 		} | 		} | ||||||
| 		err := d.v4.RenewUser(ctx, stmts, req.Username, req.Expiration.NewExpiration) | 		err := d.v4.RenewUser(ctx, stmts, req.Username, req.Expiration.NewExpiration) | ||||||
| @@ -148,7 +148,7 @@ func (d databaseVersionWrapper) UpdateUser(ctx context.Context, req newdbplugin. | |||||||
| // changePasswordLegacy attempts to use SetCredentials to change the password for the user with the password provided | // changePasswordLegacy attempts to use SetCredentials to change the password for the user with the password provided | ||||||
| // in ChangePassword. If that user is the root user and SetCredentials is unimplemented, it will fall back to using | // in ChangePassword. If that user is the root user and SetCredentials is unimplemented, it will fall back to using | ||||||
| // RotateRootCredentials. If not the root user, this will not use RotateRootCredentials. | // RotateRootCredentials. If not the root user, this will not use RotateRootCredentials. | ||||||
| func (d databaseVersionWrapper) changePasswordLegacy(ctx context.Context, username string, passwordChange *newdbplugin.ChangePassword, isRootUser bool) (saveConfig map[string]interface{}, err error) { | func (d databaseVersionWrapper) changePasswordLegacy(ctx context.Context, username string, passwordChange *v5.ChangePassword, isRootUser bool) (saveConfig map[string]interface{}, err error) { | ||||||
| 	err = d.changeUserPasswordLegacy(ctx, username, passwordChange) | 	err = d.changeUserPasswordLegacy(ctx, username, passwordChange) | ||||||
|  |  | ||||||
| 	// If changing the root user's password but SetCredentials is unimplemented, fall back to RotateRootCredentials | 	// If changing the root user's password but SetCredentials is unimplemented, fall back to RotateRootCredentials | ||||||
| @@ -165,11 +165,11 @@ func (d databaseVersionWrapper) changePasswordLegacy(ctx context.Context, userna | |||||||
| 	return nil, nil | 	return nil, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (d databaseVersionWrapper) changeUserPasswordLegacy(ctx context.Context, username string, passwordChange *newdbplugin.ChangePassword) (err error) { | func (d databaseVersionWrapper) changeUserPasswordLegacy(ctx context.Context, username string, passwordChange *v5.ChangePassword) (err error) { | ||||||
| 	stmts := dbplugin.Statements{ | 	stmts := v4.Statements{ | ||||||
| 		Rotation: passwordChange.Statements.Commands, | 		Rotation: passwordChange.Statements.Commands, | ||||||
| 	} | 	} | ||||||
| 	staticConfig := dbplugin.StaticUserConfig{ | 	staticConfig := v4.StaticUserConfig{ | ||||||
| 		Username: username, | 		Username: username, | ||||||
| 		Password: passwordChange.NewPassword, | 		Password: passwordChange.NewPassword, | ||||||
| 	} | 	} | ||||||
| @@ -177,14 +177,14 @@ func (d databaseVersionWrapper) changeUserPasswordLegacy(ctx context.Context, us | |||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| func (d databaseVersionWrapper) changeRootUserPasswordLegacy(ctx context.Context, passwordChange *newdbplugin.ChangePassword) (saveConfig map[string]interface{}, err error) { | func (d databaseVersionWrapper) changeRootUserPasswordLegacy(ctx context.Context, passwordChange *v5.ChangePassword) (saveConfig map[string]interface{}, err error) { | ||||||
| 	return d.v4.RotateRootCredentials(ctx, passwordChange.Statements.Commands) | 	return d.v4.RotateRootCredentials(ctx, passwordChange.Statements.Commands) | ||||||
| } | } | ||||||
|  |  | ||||||
| // DeleteUser in the underlying database. Errors if the wrapper does not contain an underlying database. | // DeleteUser in the underlying database. Errors if the wrapper does not contain an underlying database. | ||||||
| func (d databaseVersionWrapper) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserRequest) (newdbplugin.DeleteUserResponse, error) { | func (d databaseVersionWrapper) DeleteUser(ctx context.Context, req v5.DeleteUserRequest) (v5.DeleteUserResponse, error) { | ||||||
| 	if !d.isV5() && !d.isV4() { | 	if !d.isV5() && !d.isV4() { | ||||||
| 		return newdbplugin.DeleteUserResponse{}, fmt.Errorf("no underlying database specified") | 		return v5.DeleteUserResponse{}, fmt.Errorf("no underlying database specified") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// v5 Database | 	// v5 Database | ||||||
| @@ -193,11 +193,11 @@ func (d databaseVersionWrapper) DeleteUser(ctx context.Context, req newdbplugin. | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// v4 Database | 	// v4 Database | ||||||
| 	stmts := dbplugin.Statements{ | 	stmts := v4.Statements{ | ||||||
| 		Revocation: req.Statements.Commands, | 		Revocation: req.Statements.Commands, | ||||||
| 	} | 	} | ||||||
| 	err := d.v4.RevokeUser(ctx, stmts, req.Username) | 	err := d.v4.RevokeUser(ctx, stmts, req.Username) | ||||||
| 	return newdbplugin.DeleteUserResponse{}, err | 	return v5.DeleteUserResponse{}, err | ||||||
| } | } | ||||||
|  |  | ||||||
| // Type of the underlying database. Errors if the wrapper does not contain an underlying database. | // Type of the underlying database. Errors if the wrapper does not contain an underlying database. | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/logical" | 	"github.com/hashicorp/vault/sdk/logical" | ||||||
| 	"github.com/stretchr/testify/mock" | 	"github.com/stretchr/testify/mock" | ||||||
| 	"google.golang.org/grpc/codes" | 	"google.golang.org/grpc/codes" | ||||||
| @@ -18,13 +18,13 @@ import ( | |||||||
| func TestInitDatabase_missingDB(t *testing.T) { | func TestInitDatabase_missingDB(t *testing.T) { | ||||||
| 	dbw := databaseVersionWrapper{} | 	dbw := databaseVersionWrapper{} | ||||||
|  |  | ||||||
| 	req := newdbplugin.InitializeRequest{} | 	req := v5.InitializeRequest{} | ||||||
| 	resp, err := dbw.Initialize(context.Background(), req) | 	resp, err := dbw.Initialize(context.Background(), req) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		t.Fatalf("err expected, got nil") | 		t.Fatalf("err expected, got nil") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expectedResp := newdbplugin.InitializeResponse{} | 	expectedResp := v5.InitializeResponse{} | ||||||
| 	if !reflect.DeepEqual(resp, expectedResp) { | 	if !reflect.DeepEqual(resp, expectedResp) { | ||||||
| 		t.Fatalf("Actual resp: %#v\nExpected resp: %#v", resp, expectedResp) | 		t.Fatalf("Actual resp: %#v\nExpected resp: %#v", resp, expectedResp) | ||||||
| 	} | 	} | ||||||
| @@ -32,31 +32,31 @@ func TestInitDatabase_missingDB(t *testing.T) { | |||||||
|  |  | ||||||
| func TestInitDatabase_newDB(t *testing.T) { | func TestInitDatabase_newDB(t *testing.T) { | ||||||
| 	type testCase struct { | 	type testCase struct { | ||||||
| 		req newdbplugin.InitializeRequest | 		req v5.InitializeRequest | ||||||
|  |  | ||||||
| 		newInitResp  newdbplugin.InitializeResponse | 		newInitResp  v5.InitializeResponse | ||||||
| 		newInitErr   error | 		newInitErr   error | ||||||
| 		newInitCalls int | 		newInitCalls int | ||||||
|  |  | ||||||
| 		expectedResp newdbplugin.InitializeResponse | 		expectedResp v5.InitializeResponse | ||||||
| 		expectErr    bool | 		expectErr    bool | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tests := map[string]testCase{ | 	tests := map[string]testCase{ | ||||||
| 		"success": { | 		"success": { | ||||||
| 			req: newdbplugin.InitializeRequest{ | 			req: v5.InitializeRequest{ | ||||||
| 				Config: map[string]interface{}{ | 				Config: map[string]interface{}{ | ||||||
| 					"foo": "bar", | 					"foo": "bar", | ||||||
| 				}, | 				}, | ||||||
| 				VerifyConnection: true, | 				VerifyConnection: true, | ||||||
| 			}, | 			}, | ||||||
| 			newInitResp: newdbplugin.InitializeResponse{ | 			newInitResp: v5.InitializeResponse{ | ||||||
| 				Config: map[string]interface{}{ | 				Config: map[string]interface{}{ | ||||||
| 					"foo": "bar", | 					"foo": "bar", | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 			newInitCalls: 1, | 			newInitCalls: 1, | ||||||
| 			expectedResp: newdbplugin.InitializeResponse{ | 			expectedResp: v5.InitializeResponse{ | ||||||
| 				Config: map[string]interface{}{ | 				Config: map[string]interface{}{ | ||||||
| 					"foo": "bar", | 					"foo": "bar", | ||||||
| 				}, | 				}, | ||||||
| @@ -64,16 +64,16 @@ func TestInitDatabase_newDB(t *testing.T) { | |||||||
| 			expectErr: false, | 			expectErr: false, | ||||||
| 		}, | 		}, | ||||||
| 		"error": { | 		"error": { | ||||||
| 			req: newdbplugin.InitializeRequest{ | 			req: v5.InitializeRequest{ | ||||||
| 				Config: map[string]interface{}{ | 				Config: map[string]interface{}{ | ||||||
| 					"foo": "bar", | 					"foo": "bar", | ||||||
| 				}, | 				}, | ||||||
| 				VerifyConnection: true, | 				VerifyConnection: true, | ||||||
| 			}, | 			}, | ||||||
| 			newInitResp:  newdbplugin.InitializeResponse{}, | 			newInitResp:  v5.InitializeResponse{}, | ||||||
| 			newInitErr:   fmt.Errorf("test error"), | 			newInitErr:   fmt.Errorf("test error"), | ||||||
| 			newInitCalls: 1, | 			newInitCalls: 1, | ||||||
| 			expectedResp: newdbplugin.InitializeResponse{}, | 			expectedResp: v5.InitializeResponse{}, | ||||||
| 			expectErr:    true, | 			expectErr:    true, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| @@ -106,19 +106,19 @@ func TestInitDatabase_newDB(t *testing.T) { | |||||||
|  |  | ||||||
| func TestInitDatabase_legacyDB(t *testing.T) { | func TestInitDatabase_legacyDB(t *testing.T) { | ||||||
| 	type testCase struct { | 	type testCase struct { | ||||||
| 		req newdbplugin.InitializeRequest | 		req v5.InitializeRequest | ||||||
|  |  | ||||||
| 		initConfig map[string]interface{} | 		initConfig map[string]interface{} | ||||||
| 		initErr    error | 		initErr    error | ||||||
| 		initCalls  int | 		initCalls  int | ||||||
|  |  | ||||||
| 		expectedResp newdbplugin.InitializeResponse | 		expectedResp v5.InitializeResponse | ||||||
| 		expectErr    bool | 		expectErr    bool | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tests := map[string]testCase{ | 	tests := map[string]testCase{ | ||||||
| 		"success": { | 		"success": { | ||||||
| 			req: newdbplugin.InitializeRequest{ | 			req: v5.InitializeRequest{ | ||||||
| 				Config: map[string]interface{}{ | 				Config: map[string]interface{}{ | ||||||
| 					"foo": "bar", | 					"foo": "bar", | ||||||
| 				}, | 				}, | ||||||
| @@ -128,7 +128,7 @@ func TestInitDatabase_legacyDB(t *testing.T) { | |||||||
| 				"foo": "bar", | 				"foo": "bar", | ||||||
| 			}, | 			}, | ||||||
| 			initCalls: 1, | 			initCalls: 1, | ||||||
| 			expectedResp: newdbplugin.InitializeResponse{ | 			expectedResp: v5.InitializeResponse{ | ||||||
| 				Config: map[string]interface{}{ | 				Config: map[string]interface{}{ | ||||||
| 					"foo": "bar", | 					"foo": "bar", | ||||||
| 				}, | 				}, | ||||||
| @@ -136,7 +136,7 @@ func TestInitDatabase_legacyDB(t *testing.T) { | |||||||
| 			expectErr: false, | 			expectErr: false, | ||||||
| 		}, | 		}, | ||||||
| 		"error": { | 		"error": { | ||||||
| 			req: newdbplugin.InitializeRequest{ | 			req: v5.InitializeRequest{ | ||||||
| 				Config: map[string]interface{}{ | 				Config: map[string]interface{}{ | ||||||
| 					"foo": "bar", | 					"foo": "bar", | ||||||
| 				}, | 				}, | ||||||
| @@ -144,7 +144,7 @@ func TestInitDatabase_legacyDB(t *testing.T) { | |||||||
| 			}, | 			}, | ||||||
| 			initErr:      fmt.Errorf("test error"), | 			initErr:      fmt.Errorf("test error"), | ||||||
| 			initCalls:    1, | 			initCalls:    1, | ||||||
| 			expectedResp: newdbplugin.InitializeResponse{}, | 			expectedResp: v5.InitializeResponse{}, | ||||||
| 			expectErr:    true, | 			expectErr:    true, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| @@ -348,13 +348,13 @@ func TestGeneratePassword_no_policy(t *testing.T) { | |||||||
| func TestNewUser_missingDB(t *testing.T) { | func TestNewUser_missingDB(t *testing.T) { | ||||||
| 	dbw := databaseVersionWrapper{} | 	dbw := databaseVersionWrapper{} | ||||||
|  |  | ||||||
| 	req := newdbplugin.NewUserRequest{} | 	req := v5.NewUserRequest{} | ||||||
| 	resp, pass, err := dbw.NewUser(context.Background(), req) | 	resp, pass, err := dbw.NewUser(context.Background(), req) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		t.Fatalf("err expected, got nil") | 		t.Fatalf("err expected, got nil") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expectedResp := newdbplugin.NewUserResponse{} | 	expectedResp := v5.NewUserResponse{} | ||||||
| 	if !reflect.DeepEqual(resp, expectedResp) { | 	if !reflect.DeepEqual(resp, expectedResp) { | ||||||
| 		t.Fatalf("Actual resp: %#v\nExpected resp: %#v", resp, expectedResp) | 		t.Fatalf("Actual resp: %#v\nExpected resp: %#v", resp, expectedResp) | ||||||
| 	} | 	} | ||||||
| @@ -366,41 +366,41 @@ func TestNewUser_missingDB(t *testing.T) { | |||||||
|  |  | ||||||
| func TestNewUser_newDB(t *testing.T) { | func TestNewUser_newDB(t *testing.T) { | ||||||
| 	type testCase struct { | 	type testCase struct { | ||||||
| 		req newdbplugin.NewUserRequest | 		req v5.NewUserRequest | ||||||
|  |  | ||||||
| 		newUserResp  newdbplugin.NewUserResponse | 		newUserResp  v5.NewUserResponse | ||||||
| 		newUserErr   error | 		newUserErr   error | ||||||
| 		newUserCalls int | 		newUserCalls int | ||||||
|  |  | ||||||
| 		expectedResp newdbplugin.NewUserResponse | 		expectedResp v5.NewUserResponse | ||||||
| 		expectErr    bool | 		expectErr    bool | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tests := map[string]testCase{ | 	tests := map[string]testCase{ | ||||||
| 		"success": { | 		"success": { | ||||||
| 			req: newdbplugin.NewUserRequest{ | 			req: v5.NewUserRequest{ | ||||||
| 				Password: "new_password", | 				Password: "new_password", | ||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
| 			newUserResp: newdbplugin.NewUserResponse{ | 			newUserResp: v5.NewUserResponse{ | ||||||
| 				Username: "newuser", | 				Username: "newuser", | ||||||
| 			}, | 			}, | ||||||
| 			newUserCalls: 1, | 			newUserCalls: 1, | ||||||
|  |  | ||||||
| 			expectedResp: newdbplugin.NewUserResponse{ | 			expectedResp: v5.NewUserResponse{ | ||||||
| 				Username: "newuser", | 				Username: "newuser", | ||||||
| 			}, | 			}, | ||||||
| 			expectErr: false, | 			expectErr: false, | ||||||
| 		}, | 		}, | ||||||
| 		"error": { | 		"error": { | ||||||
| 			req: newdbplugin.NewUserRequest{ | 			req: v5.NewUserRequest{ | ||||||
| 				Password: "new_password", | 				Password: "new_password", | ||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
| 			newUserErr:   fmt.Errorf("test error"), | 			newUserErr:   fmt.Errorf("test error"), | ||||||
| 			newUserCalls: 1, | 			newUserCalls: 1, | ||||||
|  |  | ||||||
| 			expectedResp: newdbplugin.NewUserResponse{}, | 			expectedResp: v5.NewUserResponse{}, | ||||||
| 			expectErr:    true, | 			expectErr:    true, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| @@ -437,21 +437,21 @@ func TestNewUser_newDB(t *testing.T) { | |||||||
|  |  | ||||||
| func TestNewUser_legacyDB(t *testing.T) { | func TestNewUser_legacyDB(t *testing.T) { | ||||||
| 	type testCase struct { | 	type testCase struct { | ||||||
| 		req newdbplugin.NewUserRequest | 		req v5.NewUserRequest | ||||||
|  |  | ||||||
| 		createUserUsername string | 		createUserUsername string | ||||||
| 		createUserPassword string | 		createUserPassword string | ||||||
| 		createUserErr      error | 		createUserErr      error | ||||||
| 		createUserCalls    int | 		createUserCalls    int | ||||||
|  |  | ||||||
| 		expectedResp     newdbplugin.NewUserResponse | 		expectedResp     v5.NewUserResponse | ||||||
| 		expectedPassword string | 		expectedPassword string | ||||||
| 		expectErr        bool | 		expectErr        bool | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tests := map[string]testCase{ | 	tests := map[string]testCase{ | ||||||
| 		"success": { | 		"success": { | ||||||
| 			req: newdbplugin.NewUserRequest{ | 			req: v5.NewUserRequest{ | ||||||
| 				Password: "new_password", | 				Password: "new_password", | ||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
| @@ -459,21 +459,21 @@ func TestNewUser_legacyDB(t *testing.T) { | |||||||
| 			createUserPassword: "securepassword", | 			createUserPassword: "securepassword", | ||||||
| 			createUserCalls:    1, | 			createUserCalls:    1, | ||||||
|  |  | ||||||
| 			expectedResp: newdbplugin.NewUserResponse{ | 			expectedResp: v5.NewUserResponse{ | ||||||
| 				Username: "newuser", | 				Username: "newuser", | ||||||
| 			}, | 			}, | ||||||
| 			expectedPassword: "securepassword", | 			expectedPassword: "securepassword", | ||||||
| 			expectErr:        false, | 			expectErr:        false, | ||||||
| 		}, | 		}, | ||||||
| 		"error": { | 		"error": { | ||||||
| 			req: newdbplugin.NewUserRequest{ | 			req: v5.NewUserRequest{ | ||||||
| 				Password: "new_password", | 				Password: "new_password", | ||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
| 			createUserErr:   fmt.Errorf("test error"), | 			createUserErr:   fmt.Errorf("test error"), | ||||||
| 			createUserCalls: 1, | 			createUserCalls: 1, | ||||||
|  |  | ||||||
| 			expectedResp: newdbplugin.NewUserResponse{}, | 			expectedResp: v5.NewUserResponse{}, | ||||||
| 			expectErr:    true, | 			expectErr:    true, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| @@ -511,7 +511,7 @@ func TestNewUser_legacyDB(t *testing.T) { | |||||||
| func TestUpdateUser_missingDB(t *testing.T) { | func TestUpdateUser_missingDB(t *testing.T) { | ||||||
| 	dbw := databaseVersionWrapper{} | 	dbw := databaseVersionWrapper{} | ||||||
|  |  | ||||||
| 	req := newdbplugin.UpdateUserRequest{} | 	req := v5.UpdateUserRequest{} | ||||||
| 	resp, err := dbw.UpdateUser(context.Background(), req, false) | 	resp, err := dbw.UpdateUser(context.Background(), req, false) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		t.Fatalf("err expected, got nil") | 		t.Fatalf("err expected, got nil") | ||||||
| @@ -525,25 +525,25 @@ func TestUpdateUser_missingDB(t *testing.T) { | |||||||
|  |  | ||||||
| func TestUpdateUser_newDB(t *testing.T) { | func TestUpdateUser_newDB(t *testing.T) { | ||||||
| 	type testCase struct { | 	type testCase struct { | ||||||
| 		req newdbplugin.UpdateUserRequest | 		req v5.UpdateUserRequest | ||||||
|  |  | ||||||
| 		updateUserErr   error | 		updateUserErr   error | ||||||
| 		updateUserCalls int | 		updateUserCalls int | ||||||
|  |  | ||||||
| 		expectedResp newdbplugin.UpdateUserResponse | 		expectedResp v5.UpdateUserResponse | ||||||
| 		expectErr    bool | 		expectErr    bool | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tests := map[string]testCase{ | 	tests := map[string]testCase{ | ||||||
| 		"success": { | 		"success": { | ||||||
| 			req: newdbplugin.UpdateUserRequest{ | 			req: v5.UpdateUserRequest{ | ||||||
| 				Username: "existing_user", | 				Username: "existing_user", | ||||||
| 			}, | 			}, | ||||||
| 			updateUserCalls: 1, | 			updateUserCalls: 1, | ||||||
| 			expectErr:       false, | 			expectErr:       false, | ||||||
| 		}, | 		}, | ||||||
| 		"error": { | 		"error": { | ||||||
| 			req: newdbplugin.UpdateUserRequest{ | 			req: v5.UpdateUserRequest{ | ||||||
| 				Username: "existing_user", | 				Username: "existing_user", | ||||||
| 			}, | 			}, | ||||||
| 			updateUserErr:   fmt.Errorf("test error"), | 			updateUserErr:   fmt.Errorf("test error"), | ||||||
| @@ -556,7 +556,7 @@ func TestUpdateUser_newDB(t *testing.T) { | |||||||
| 		t.Run(name, func(t *testing.T) { | 		t.Run(name, func(t *testing.T) { | ||||||
| 			newDB := new(mockNewDatabase) | 			newDB := new(mockNewDatabase) | ||||||
| 			newDB.On("UpdateUser", mock.Anything, mock.Anything). | 			newDB.On("UpdateUser", mock.Anything, mock.Anything). | ||||||
| 				Return(newdbplugin.UpdateUserResponse{}, test.updateUserErr) | 				Return(v5.UpdateUserResponse{}, test.updateUserErr) | ||||||
| 			defer newDB.AssertNumberOfCalls(t, "UpdateUser", test.updateUserCalls) | 			defer newDB.AssertNumberOfCalls(t, "UpdateUser", test.updateUserCalls) | ||||||
|  |  | ||||||
| 			dbw := databaseVersionWrapper{ | 			dbw := databaseVersionWrapper{ | ||||||
| @@ -576,7 +576,7 @@ func TestUpdateUser_newDB(t *testing.T) { | |||||||
|  |  | ||||||
| func TestUpdateUser_legacyDB(t *testing.T) { | func TestUpdateUser_legacyDB(t *testing.T) { | ||||||
| 	type testCase struct { | 	type testCase struct { | ||||||
| 		req        newdbplugin.UpdateUserRequest | 		req        v5.UpdateUserRequest | ||||||
| 		isRootUser bool | 		isRootUser bool | ||||||
|  |  | ||||||
| 		setCredentialsErr   error | 		setCredentialsErr   error | ||||||
| @@ -595,7 +595,7 @@ func TestUpdateUser_legacyDB(t *testing.T) { | |||||||
|  |  | ||||||
| 	tests := map[string]testCase{ | 	tests := map[string]testCase{ | ||||||
| 		"missing changes": { | 		"missing changes": { | ||||||
| 			req: newdbplugin.UpdateUserRequest{ | 			req: v5.UpdateUserRequest{ | ||||||
| 				Username: "existing_user", | 				Username: "existing_user", | ||||||
| 			}, | 			}, | ||||||
| 			isRootUser: false, | 			isRootUser: false, | ||||||
| @@ -607,10 +607,10 @@ func TestUpdateUser_legacyDB(t *testing.T) { | |||||||
| 			expectErr: true, | 			expectErr: true, | ||||||
| 		}, | 		}, | ||||||
| 		"both password and expiration changes": { | 		"both password and expiration changes": { | ||||||
| 			req: newdbplugin.UpdateUserRequest{ | 			req: v5.UpdateUserRequest{ | ||||||
| 				Username:   "existing_user", | 				Username:   "existing_user", | ||||||
| 				Password:   &newdbplugin.ChangePassword{}, | 				Password:   &v5.ChangePassword{}, | ||||||
| 				Expiration: &newdbplugin.ChangeExpiration{}, | 				Expiration: &v5.ChangeExpiration{}, | ||||||
| 			}, | 			}, | ||||||
| 			isRootUser: false, | 			isRootUser: false, | ||||||
|  |  | ||||||
| @@ -621,9 +621,9 @@ func TestUpdateUser_legacyDB(t *testing.T) { | |||||||
| 			expectErr: true, | 			expectErr: true, | ||||||
| 		}, | 		}, | ||||||
| 		"change password - SetCredentials": { | 		"change password - SetCredentials": { | ||||||
| 			req: newdbplugin.UpdateUserRequest{ | 			req: v5.UpdateUserRequest{ | ||||||
| 				Username: "existing_user", | 				Username: "existing_user", | ||||||
| 				Password: &newdbplugin.ChangePassword{ | 				Password: &v5.ChangePassword{ | ||||||
| 					NewPassword: "newpassowrd", | 					NewPassword: "newpassowrd", | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| @@ -638,9 +638,9 @@ func TestUpdateUser_legacyDB(t *testing.T) { | |||||||
| 			expectErr:      false, | 			expectErr:      false, | ||||||
| 		}, | 		}, | ||||||
| 		"change password - SetCredentials failed": { | 		"change password - SetCredentials failed": { | ||||||
| 			req: newdbplugin.UpdateUserRequest{ | 			req: v5.UpdateUserRequest{ | ||||||
| 				Username: "existing_user", | 				Username: "existing_user", | ||||||
| 				Password: &newdbplugin.ChangePassword{ | 				Password: &v5.ChangePassword{ | ||||||
| 					NewPassword: "newpassowrd", | 					NewPassword: "newpassowrd", | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| @@ -655,9 +655,9 @@ func TestUpdateUser_legacyDB(t *testing.T) { | |||||||
| 			expectErr:      true, | 			expectErr:      true, | ||||||
| 		}, | 		}, | ||||||
| 		"change password - SetCredentials unimplemented but not a root user": { | 		"change password - SetCredentials unimplemented but not a root user": { | ||||||
| 			req: newdbplugin.UpdateUserRequest{ | 			req: v5.UpdateUserRequest{ | ||||||
| 				Username: "existing_user", | 				Username: "existing_user", | ||||||
| 				Password: &newdbplugin.ChangePassword{ | 				Password: &v5.ChangePassword{ | ||||||
| 					NewPassword: "newpassowrd", | 					NewPassword: "newpassowrd", | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| @@ -673,9 +673,9 @@ func TestUpdateUser_legacyDB(t *testing.T) { | |||||||
| 			expectErr:      true, | 			expectErr:      true, | ||||||
| 		}, | 		}, | ||||||
| 		"change password - RotateRootCredentials": { | 		"change password - RotateRootCredentials": { | ||||||
| 			req: newdbplugin.UpdateUserRequest{ | 			req: v5.UpdateUserRequest{ | ||||||
| 				Username: "existing_user", | 				Username: "existing_user", | ||||||
| 				Password: &newdbplugin.ChangePassword{ | 				Password: &v5.ChangePassword{ | ||||||
| 					NewPassword: "newpassowrd", | 					NewPassword: "newpassowrd", | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| @@ -697,9 +697,9 @@ func TestUpdateUser_legacyDB(t *testing.T) { | |||||||
| 			expectErr: false, | 			expectErr: false, | ||||||
| 		}, | 		}, | ||||||
| 		"change password - RotateRootCredentials failed": { | 		"change password - RotateRootCredentials failed": { | ||||||
| 			req: newdbplugin.UpdateUserRequest{ | 			req: v5.UpdateUserRequest{ | ||||||
| 				Username: "existing_user", | 				Username: "existing_user", | ||||||
| 				Password: &newdbplugin.ChangePassword{ | 				Password: &v5.ChangePassword{ | ||||||
| 					NewPassword: "newpassowrd", | 					NewPassword: "newpassowrd", | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| @@ -717,9 +717,9 @@ func TestUpdateUser_legacyDB(t *testing.T) { | |||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		"change expiration": { | 		"change expiration": { | ||||||
| 			req: newdbplugin.UpdateUserRequest{ | 			req: v5.UpdateUserRequest{ | ||||||
| 				Username: "existing_user", | 				Username: "existing_user", | ||||||
| 				Expiration: &newdbplugin.ChangeExpiration{ | 				Expiration: &v5.ChangeExpiration{ | ||||||
| 					NewExpiration: time.Now(), | 					NewExpiration: time.Now(), | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| @@ -735,9 +735,9 @@ func TestUpdateUser_legacyDB(t *testing.T) { | |||||||
| 			expectErr:      false, | 			expectErr:      false, | ||||||
| 		}, | 		}, | ||||||
| 		"change expiration failed": { | 		"change expiration failed": { | ||||||
| 			req: newdbplugin.UpdateUserRequest{ | 			req: v5.UpdateUserRequest{ | ||||||
| 				Username: "existing_user", | 				Username: "existing_user", | ||||||
| 				Expiration: &newdbplugin.ChangeExpiration{ | 				Expiration: &v5.ChangeExpiration{ | ||||||
| 					NewExpiration: time.Now(), | 					NewExpiration: time.Now(), | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| @@ -791,7 +791,7 @@ func TestUpdateUser_legacyDB(t *testing.T) { | |||||||
| func TestDeleteUser_missingDB(t *testing.T) { | func TestDeleteUser_missingDB(t *testing.T) { | ||||||
| 	dbw := databaseVersionWrapper{} | 	dbw := databaseVersionWrapper{} | ||||||
|  |  | ||||||
| 	req := newdbplugin.DeleteUserRequest{} | 	req := v5.DeleteUserRequest{} | ||||||
| 	_, err := dbw.DeleteUser(context.Background(), req) | 	_, err := dbw.DeleteUser(context.Background(), req) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		t.Fatalf("err expected, got nil") | 		t.Fatalf("err expected, got nil") | ||||||
| @@ -800,7 +800,7 @@ func TestDeleteUser_missingDB(t *testing.T) { | |||||||
|  |  | ||||||
| func TestDeleteUser_newDB(t *testing.T) { | func TestDeleteUser_newDB(t *testing.T) { | ||||||
| 	type testCase struct { | 	type testCase struct { | ||||||
| 		req newdbplugin.DeleteUserRequest | 		req v5.DeleteUserRequest | ||||||
|  |  | ||||||
| 		deleteUserErr   error | 		deleteUserErr   error | ||||||
| 		deleteUserCalls int | 		deleteUserCalls int | ||||||
| @@ -810,7 +810,7 @@ func TestDeleteUser_newDB(t *testing.T) { | |||||||
|  |  | ||||||
| 	tests := map[string]testCase{ | 	tests := map[string]testCase{ | ||||||
| 		"success": { | 		"success": { | ||||||
| 			req: newdbplugin.DeleteUserRequest{ | 			req: v5.DeleteUserRequest{ | ||||||
| 				Username: "existing_user", | 				Username: "existing_user", | ||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
| @@ -820,7 +820,7 @@ func TestDeleteUser_newDB(t *testing.T) { | |||||||
| 			expectErr: false, | 			expectErr: false, | ||||||
| 		}, | 		}, | ||||||
| 		"error": { | 		"error": { | ||||||
| 			req: newdbplugin.DeleteUserRequest{ | 			req: v5.DeleteUserRequest{ | ||||||
| 				Username: "existing_user", | 				Username: "existing_user", | ||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
| @@ -835,7 +835,7 @@ func TestDeleteUser_newDB(t *testing.T) { | |||||||
| 		t.Run(name, func(t *testing.T) { | 		t.Run(name, func(t *testing.T) { | ||||||
| 			newDB := new(mockNewDatabase) | 			newDB := new(mockNewDatabase) | ||||||
| 			newDB.On("DeleteUser", mock.Anything, mock.Anything). | 			newDB.On("DeleteUser", mock.Anything, mock.Anything). | ||||||
| 				Return(newdbplugin.DeleteUserResponse{}, test.deleteUserErr) | 				Return(v5.DeleteUserResponse{}, test.deleteUserErr) | ||||||
| 			defer newDB.AssertNumberOfCalls(t, "DeleteUser", test.deleteUserCalls) | 			defer newDB.AssertNumberOfCalls(t, "DeleteUser", test.deleteUserCalls) | ||||||
|  |  | ||||||
| 			dbw := databaseVersionWrapper{ | 			dbw := databaseVersionWrapper{ | ||||||
| @@ -855,7 +855,7 @@ func TestDeleteUser_newDB(t *testing.T) { | |||||||
|  |  | ||||||
| func TestDeleteUser_legacyDB(t *testing.T) { | func TestDeleteUser_legacyDB(t *testing.T) { | ||||||
| 	type testCase struct { | 	type testCase struct { | ||||||
| 		req newdbplugin.DeleteUserRequest | 		req v5.DeleteUserRequest | ||||||
|  |  | ||||||
| 		revokeUserErr   error | 		revokeUserErr   error | ||||||
| 		revokeUserCalls int | 		revokeUserCalls int | ||||||
| @@ -865,7 +865,7 @@ func TestDeleteUser_legacyDB(t *testing.T) { | |||||||
|  |  | ||||||
| 	tests := map[string]testCase{ | 	tests := map[string]testCase{ | ||||||
| 		"success": { | 		"success": { | ||||||
| 			req: newdbplugin.DeleteUserRequest{ | 			req: v5.DeleteUserRequest{ | ||||||
| 				Username: "existing_user", | 				Username: "existing_user", | ||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
| @@ -875,7 +875,7 @@ func TestDeleteUser_legacyDB(t *testing.T) { | |||||||
| 			expectErr: false, | 			expectErr: false, | ||||||
| 		}, | 		}, | ||||||
| 		"error": { | 		"error": { | ||||||
| 			req: newdbplugin.DeleteUserRequest{ | 			req: v5.DeleteUserRequest{ | ||||||
| 				Username: "existing_user", | 				Username: "existing_user", | ||||||
| 			}, | 			}, | ||||||
|  |  | ||||||
|   | |||||||
| @@ -92,7 +92,7 @@ func TestPlugin_lifecycle(t *testing.T) { | |||||||
| 				Storage:   config.StorageView, | 				Storage:   config.StorageView, | ||||||
| 				Data:      test.configData, | 				Data:      test.configData, | ||||||
| 			} | 			} | ||||||
| 			ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) | 			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) | ||||||
| 			defer cancel() | 			defer cancel() | ||||||
|  |  | ||||||
| 			resp, err := b.HandleRequest(ctx, req) | 			resp, err := b.HandleRequest(ctx, req) | ||||||
| @@ -113,7 +113,7 @@ func TestPlugin_lifecycle(t *testing.T) { | |||||||
| 				Path:      fmt.Sprintf("rotate-root/%s", test.dbName), | 				Path:      fmt.Sprintf("rotate-root/%s", test.dbName), | ||||||
| 				Storage:   config.StorageView, | 				Storage:   config.StorageView, | ||||||
| 			} | 			} | ||||||
| 			ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second) | 			ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) | ||||||
| 			defer cancel() | 			defer cancel() | ||||||
|  |  | ||||||
| 			resp, err = b.HandleRequest(ctx, req) | 			resp, err = b.HandleRequest(ctx, req) | ||||||
| @@ -136,7 +136,7 @@ func TestPlugin_lifecycle(t *testing.T) { | |||||||
| 					"max_ttl":     "1m", | 					"max_ttl":     "1m", | ||||||
| 				}, | 				}, | ||||||
| 			} | 			} | ||||||
| 			ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second) | 			ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) | ||||||
| 			defer cancel() | 			defer cancel() | ||||||
|  |  | ||||||
| 			resp, err = b.HandleRequest(ctx, req) | 			resp, err = b.HandleRequest(ctx, req) | ||||||
| @@ -156,7 +156,7 @@ func TestPlugin_lifecycle(t *testing.T) { | |||||||
| 				Path:      fmt.Sprintf("creds/%s", dynamicRoleName), | 				Path:      fmt.Sprintf("creds/%s", dynamicRoleName), | ||||||
| 				Storage:   config.StorageView, | 				Storage:   config.StorageView, | ||||||
| 			} | 			} | ||||||
| 			ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second) | 			ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) | ||||||
| 			defer cancel() | 			defer cancel() | ||||||
|  |  | ||||||
| 			resp, err = b.HandleRequest(ctx, req) | 			resp, err = b.HandleRequest(ctx, req) | ||||||
| @@ -182,7 +182,7 @@ func TestPlugin_lifecycle(t *testing.T) { | |||||||
| 					"rotation_period": "5", | 					"rotation_period": "5", | ||||||
| 				}, | 				}, | ||||||
| 			} | 			} | ||||||
| 			ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second) | 			ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) | ||||||
| 			defer cancel() | 			defer cancel() | ||||||
|  |  | ||||||
| 			resp, err = b.HandleRequest(ctx, req) | 			resp, err = b.HandleRequest(ctx, req) | ||||||
| @@ -202,7 +202,7 @@ func TestPlugin_lifecycle(t *testing.T) { | |||||||
| 				Path:      fmt.Sprintf("static-creds/%s", staticRoleName), | 				Path:      fmt.Sprintf("static-creds/%s", staticRoleName), | ||||||
| 				Storage:   config.StorageView, | 				Storage:   config.StorageView, | ||||||
| 			} | 			} | ||||||
| 			ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second) | 			ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) | ||||||
| 			defer cancel() | 			defer cancel() | ||||||
|  |  | ||||||
| 			resp, err = b.HandleRequest(ctx, req) | 			resp, err = b.HandleRequest(ctx, req) | ||||||
|   | |||||||
| @@ -8,9 +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" | ||||||
|  | 	dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/credsutil" | 	"github.com/hashicorp/vault/sdk/database/helper/credsutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" |  | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/strutil" | 	"github.com/hashicorp/vault/sdk/helper/strutil" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -21,7 +21,7 @@ const ( | |||||||
| 	cassandraTypeName        = "cassandra" | 	cassandraTypeName        = "cassandra" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var _ newdbplugin.Database = &Cassandra{} | var _ dbplugin.Database = &Cassandra{} | ||||||
|  |  | ||||||
| // Cassandra is an implementation of Database interface | // Cassandra is an implementation of Database interface | ||||||
| type Cassandra struct { | type Cassandra struct { | ||||||
| @@ -31,7 +31,7 @@ type Cassandra struct { | |||||||
| // New returns a new Cassandra instance | // New returns a new Cassandra instance | ||||||
| func New() (interface{}, error) { | func New() (interface{}, error) { | ||||||
| 	db := new() | 	db := new() | ||||||
| 	dbType := newdbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) | 	dbType := dbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) | ||||||
|  |  | ||||||
| 	return dbType, nil | 	return dbType, nil | ||||||
| } | } | ||||||
| @@ -52,7 +52,7 @@ func Run(apiTLSConfig *api.TLSConfig) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	newdbplugin.Serve(dbType.(newdbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | 	dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -73,13 +73,13 @@ func (c *Cassandra) getConnection(ctx context.Context) (*gocql.Session, error) { | |||||||
|  |  | ||||||
| // NewUser generates the username/password on the underlying Cassandra secret backend as instructed by | // NewUser generates the username/password on the underlying Cassandra secret backend as instructed by | ||||||
| // the statements provided. | // the statements provided. | ||||||
| func (c *Cassandra) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) (newdbplugin.NewUserResponse, error) { | func (c *Cassandra) NewUser(ctx context.Context, req dbplugin.NewUserRequest) (dbplugin.NewUserResponse, error) { | ||||||
| 	c.Lock() | 	c.Lock() | ||||||
| 	defer c.Unlock() | 	defer c.Unlock() | ||||||
|  |  | ||||||
| 	session, err := c.getConnection(ctx) | 	session, err := c.getConnection(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, err | 		return dbplugin.NewUserResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	creationCQL := req.Statements.Commands | 	creationCQL := req.Statements.Commands | ||||||
| @@ -100,7 +100,7 @@ func (c *Cassandra) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) | |||||||
| 		credsutil.ToLower(), | 		credsutil.ToLower(), | ||||||
| 	) | 	) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, err | 		return dbplugin.NewUserResponse{}, err | ||||||
| 	} | 	} | ||||||
| 	username = strings.ReplaceAll(username, "-", "_") | 	username = strings.ReplaceAll(username, "-", "_") | ||||||
|  |  | ||||||
| @@ -124,12 +124,12 @@ func (c *Cassandra) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) | |||||||
| 				if rollbackErr != nil { | 				if rollbackErr != nil { | ||||||
| 					err = multierror.Append(err, rollbackErr) | 					err = multierror.Append(err, rollbackErr) | ||||||
| 				} | 				} | ||||||
| 				return newdbplugin.NewUserResponse{}, err | 				return dbplugin.NewUserResponse{}, err | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	resp := newdbplugin.NewUserResponse{ | 	resp := dbplugin.NewUserResponse{ | ||||||
| 		Username: username, | 		Username: username, | ||||||
| 	} | 	} | ||||||
| 	return resp, nil | 	return resp, nil | ||||||
| @@ -158,20 +158,20 @@ func rollbackUser(ctx context.Context, session *gocql.Session, username string, | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *Cassandra) UpdateUser(ctx context.Context, req newdbplugin.UpdateUserRequest) (newdbplugin.UpdateUserResponse, error) { | func (c *Cassandra) UpdateUser(ctx context.Context, req dbplugin.UpdateUserRequest) (dbplugin.UpdateUserResponse, error) { | ||||||
| 	if req.Password == nil && req.Expiration == nil { | 	if req.Password == nil && req.Expiration == nil { | ||||||
| 		return newdbplugin.UpdateUserResponse{}, fmt.Errorf("no changes requested") | 		return dbplugin.UpdateUserResponse{}, fmt.Errorf("no changes requested") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if req.Password != nil { | 	if req.Password != nil { | ||||||
| 		err := c.changeUserPassword(ctx, req.Username, req.Password) | 		err := c.changeUserPassword(ctx, req.Username, req.Password) | ||||||
| 		return newdbplugin.UpdateUserResponse{}, err | 		return dbplugin.UpdateUserResponse{}, err | ||||||
| 	} | 	} | ||||||
| 	// Expiration is no-op | 	// Expiration is no-op | ||||||
| 	return newdbplugin.UpdateUserResponse{}, nil | 	return dbplugin.UpdateUserResponse{}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *Cassandra) changeUserPassword(ctx context.Context, username string, changePass *newdbplugin.ChangePassword) error { | func (c *Cassandra) changeUserPassword(ctx context.Context, username string, changePass *dbplugin.ChangePassword) error { | ||||||
| 	session, err := c.getConnection(ctx) | 	session, err := c.getConnection(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| @@ -206,13 +206,13 @@ func (c *Cassandra) changeUserPassword(ctx context.Context, username string, cha | |||||||
| } | } | ||||||
|  |  | ||||||
| // DeleteUser attempts to drop the specified user. | // DeleteUser attempts to drop the specified user. | ||||||
| func (c *Cassandra) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserRequest) (newdbplugin.DeleteUserResponse, error) { | func (c *Cassandra) DeleteUser(ctx context.Context, req dbplugin.DeleteUserRequest) (dbplugin.DeleteUserResponse, error) { | ||||||
| 	c.Lock() | 	c.Lock() | ||||||
| 	defer c.Unlock() | 	defer c.Unlock() | ||||||
|  |  | ||||||
| 	session, err := c.getConnection(ctx) | 	session, err := c.getConnection(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.DeleteUserResponse{}, err | 		return dbplugin.DeleteUserResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	revocationCQL := req.Statements.Commands | 	revocationCQL := req.Statements.Commands | ||||||
| @@ -240,5 +240,5 @@ func (c *Cassandra) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserRe | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return newdbplugin.DeleteUserResponse{}, result.ErrorOrNil() | 	return dbplugin.DeleteUserResponse{}, result.ErrorOrNil() | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,12 +7,11 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	dbtesting "github.com/hashicorp/vault/sdk/database/newdbplugin/testing" |  | ||||||
|  |  | ||||||
| 	backoff "github.com/cenkalti/backoff/v3" | 	backoff "github.com/cenkalti/backoff/v3" | ||||||
| 	"github.com/gocql/gocql" | 	"github.com/gocql/gocql" | ||||||
| 	"github.com/hashicorp/vault/helper/testhelpers/cassandra" | 	"github.com/hashicorp/vault/helper/testhelpers/cassandra" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
|  | 	dbtesting "github.com/hashicorp/vault/sdk/database/dbplugin/v5/testing" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func getCassandra(t *testing.T, protocolVersion interface{}) (*Cassandra, func()) { | func getCassandra(t *testing.T, protocolVersion interface{}) (*Cassandra, func()) { | ||||||
| @@ -20,7 +19,7 @@ func getCassandra(t *testing.T, protocolVersion interface{}) (*Cassandra, func() | |||||||
| 	pieces := strings.Split(connURL, ":") | 	pieces := strings.Split(connURL, ":") | ||||||
|  |  | ||||||
| 	db := new() | 	db := new() | ||||||
| 	initReq := newdbplugin.InitializeRequest{ | 	initReq := dbplugin.InitializeRequest{ | ||||||
| 		Config: map[string]interface{}{ | 		Config: map[string]interface{}{ | ||||||
| 			"hosts":            connURL, | 			"hosts":            connURL, | ||||||
| 			"port":             pieces[1], | 			"port":             pieces[1], | ||||||
| @@ -70,12 +69,12 @@ func TestCassandra_CreateUser(t *testing.T) { | |||||||
| 	defer cleanup() | 	defer cleanup() | ||||||
|  |  | ||||||
| 	password := "myreallysecurepassword" | 	password := "myreallysecurepassword" | ||||||
| 	createReq := newdbplugin.NewUserRequest{ | 	createReq := dbplugin.NewUserRequest{ | ||||||
| 		UsernameConfig: newdbplugin.UsernameMetadata{ | 		UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 			DisplayName: "test", | 			DisplayName: "test", | ||||||
| 			RoleName:    "test", | 			RoleName:    "test", | ||||||
| 		}, | 		}, | ||||||
| 		Statements: newdbplugin.Statements{ | 		Statements: dbplugin.Statements{ | ||||||
| 			Commands: []string{createUserStatements}, | 			Commands: []string{createUserStatements}, | ||||||
| 		}, | 		}, | ||||||
| 		Password:   password, | 		Password:   password, | ||||||
| @@ -98,12 +97,12 @@ func TestMyCassandra_UpdateUserPassword(t *testing.T) { | |||||||
| 	defer cleanup() | 	defer cleanup() | ||||||
|  |  | ||||||
| 	password := "myreallysecurepassword" | 	password := "myreallysecurepassword" | ||||||
| 	createReq := newdbplugin.NewUserRequest{ | 	createReq := dbplugin.NewUserRequest{ | ||||||
| 		UsernameConfig: newdbplugin.UsernameMetadata{ | 		UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 			DisplayName: "test", | 			DisplayName: "test", | ||||||
| 			RoleName:    "test", | 			RoleName:    "test", | ||||||
| 		}, | 		}, | ||||||
| 		Statements: newdbplugin.Statements{ | 		Statements: dbplugin.Statements{ | ||||||
| 			Commands: []string{createUserStatements}, | 			Commands: []string{createUserStatements}, | ||||||
| 		}, | 		}, | ||||||
| 		Password:   password, | 		Password:   password, | ||||||
| @@ -115,11 +114,11 @@ func TestMyCassandra_UpdateUserPassword(t *testing.T) { | |||||||
| 	assertCreds(t, db.Hosts, db.Port, createResp.Username, password, 5*time.Second) | 	assertCreds(t, db.Hosts, db.Port, createResp.Username, password, 5*time.Second) | ||||||
|  |  | ||||||
| 	newPassword := "somenewpassword" | 	newPassword := "somenewpassword" | ||||||
| 	updateReq := newdbplugin.UpdateUserRequest{ | 	updateReq := dbplugin.UpdateUserRequest{ | ||||||
| 		Username: createResp.Username, | 		Username: createResp.Username, | ||||||
| 		Password: &newdbplugin.ChangePassword{ | 		Password: &dbplugin.ChangePassword{ | ||||||
| 			NewPassword: newPassword, | 			NewPassword: newPassword, | ||||||
| 			Statements:  newdbplugin.Statements{}, | 			Statements:  dbplugin.Statements{}, | ||||||
| 		}, | 		}, | ||||||
| 		Expiration: nil, | 		Expiration: nil, | ||||||
| 	} | 	} | ||||||
| @@ -134,12 +133,12 @@ func TestCassandra_DeleteUser(t *testing.T) { | |||||||
| 	defer cleanup() | 	defer cleanup() | ||||||
|  |  | ||||||
| 	password := "myreallysecurepassword" | 	password := "myreallysecurepassword" | ||||||
| 	createReq := newdbplugin.NewUserRequest{ | 	createReq := dbplugin.NewUserRequest{ | ||||||
| 		UsernameConfig: newdbplugin.UsernameMetadata{ | 		UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 			DisplayName: "test", | 			DisplayName: "test", | ||||||
| 			RoleName:    "test", | 			RoleName:    "test", | ||||||
| 		}, | 		}, | ||||||
| 		Statements: newdbplugin.Statements{ | 		Statements: dbplugin.Statements{ | ||||||
| 			Commands: []string{createUserStatements}, | 			Commands: []string{createUserStatements}, | ||||||
| 		}, | 		}, | ||||||
| 		Password:   password, | 		Password:   password, | ||||||
| @@ -150,7 +149,7 @@ func TestCassandra_DeleteUser(t *testing.T) { | |||||||
|  |  | ||||||
| 	assertCreds(t, db.Hosts, db.Port, createResp.Username, password, 5*time.Second) | 	assertCreds(t, db.Hosts, db.Port, createResp.Username, password, 5*time.Second) | ||||||
|  |  | ||||||
| 	deleteReq := newdbplugin.DeleteUserRequest{ | 	deleteReq := dbplugin.DeleteUserRequest{ | ||||||
| 		Username: createResp.Username, | 		Username: createResp.Username, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,16 +8,15 @@ import ( | |||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/mitchellh/mapstructure" |  | ||||||
|  |  | ||||||
| 	"github.com/gocql/gocql" | 	"github.com/gocql/gocql" | ||||||
| 	"github.com/hashicorp/errwrap" | 	"github.com/hashicorp/errwrap" | ||||||
|  | 	dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/connutil" | 	"github.com/hashicorp/vault/sdk/database/helper/connutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" |  | ||||||
| 	"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" | ||||||
|  | 	"github.com/mitchellh/mapstructure" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // cassandraConnectionProducer implements ConnectionProducer and provides an | // cassandraConnectionProducer implements ConnectionProducer and provides an | ||||||
| @@ -52,7 +51,7 @@ type cassandraConnectionProducer struct { | |||||||
| 	sync.Mutex | 	sync.Mutex | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *cassandraConnectionProducer) Initialize(ctx context.Context, req newdbplugin.InitializeRequest) (newdbplugin.InitializeResponse, error) { | func (c *cassandraConnectionProducer) Initialize(ctx context.Context, req dbplugin.InitializeRequest) (dbplugin.InitializeResponse, error) { | ||||||
| 	c.Lock() | 	c.Lock() | ||||||
| 	defer c.Unlock() | 	defer c.Unlock() | ||||||
|  |  | ||||||
| @@ -60,7 +59,7 @@ func (c *cassandraConnectionProducer) Initialize(ctx context.Context, req newdbp | |||||||
|  |  | ||||||
| 	err := mapstructure.WeakDecode(req.Config, c) | 	err := mapstructure.WeakDecode(req.Config, c) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.InitializeResponse{}, err | 		return dbplugin.InitializeResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if c.ConnectTimeoutRaw == nil { | 	if c.ConnectTimeoutRaw == nil { | ||||||
| @@ -68,7 +67,7 @@ func (c *cassandraConnectionProducer) Initialize(ctx context.Context, req newdbp | |||||||
| 	} | 	} | ||||||
| 	c.connectTimeout, err = parseutil.ParseDurationSecond(c.ConnectTimeoutRaw) | 	c.connectTimeout, err = parseutil.ParseDurationSecond(c.ConnectTimeoutRaw) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.InitializeResponse{}, errwrap.Wrapf("invalid connect_timeout: {{err}}", err) | 		return dbplugin.InitializeResponse{}, errwrap.Wrapf("invalid connect_timeout: {{err}}", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if c.SocketKeepAliveRaw == nil { | 	if c.SocketKeepAliveRaw == nil { | ||||||
| @@ -76,16 +75,16 @@ func (c *cassandraConnectionProducer) Initialize(ctx context.Context, req newdbp | |||||||
| 	} | 	} | ||||||
| 	c.socketKeepAlive, err = parseutil.ParseDurationSecond(c.SocketKeepAliveRaw) | 	c.socketKeepAlive, err = parseutil.ParseDurationSecond(c.SocketKeepAliveRaw) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.InitializeResponse{}, errwrap.Wrapf("invalid socket_keep_alive: {{err}}", err) | 		return dbplugin.InitializeResponse{}, errwrap.Wrapf("invalid socket_keep_alive: {{err}}", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	switch { | 	switch { | ||||||
| 	case len(c.Hosts) == 0: | 	case len(c.Hosts) == 0: | ||||||
| 		return newdbplugin.InitializeResponse{}, fmt.Errorf("hosts cannot be empty") | 		return dbplugin.InitializeResponse{}, fmt.Errorf("hosts cannot be empty") | ||||||
| 	case len(c.Username) == 0: | 	case len(c.Username) == 0: | ||||||
| 		return newdbplugin.InitializeResponse{}, fmt.Errorf("username cannot be empty") | 		return dbplugin.InitializeResponse{}, fmt.Errorf("username cannot be empty") | ||||||
| 	case len(c.Password) == 0: | 	case len(c.Password) == 0: | ||||||
| 		return newdbplugin.InitializeResponse{}, fmt.Errorf("password cannot be empty") | 		return dbplugin.InitializeResponse{}, fmt.Errorf("password cannot be empty") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var certBundle *certutil.CertBundle | 	var certBundle *certutil.CertBundle | ||||||
| @@ -94,11 +93,11 @@ func (c *cassandraConnectionProducer) Initialize(ctx context.Context, req newdbp | |||||||
| 	case len(c.PemJSON) != 0: | 	case len(c.PemJSON) != 0: | ||||||
| 		parsedCertBundle, err = certutil.ParsePKIJSON([]byte(c.PemJSON)) | 		parsedCertBundle, err = certutil.ParsePKIJSON([]byte(c.PemJSON)) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return newdbplugin.InitializeResponse{}, errwrap.Wrapf("could not parse given JSON; it must be in the format of the output of the PKI backend certificate issuing command: {{err}}", err) | 			return dbplugin.InitializeResponse{}, errwrap.Wrapf("could not parse given JSON; it must be in the format of the output of the PKI backend certificate issuing command: {{err}}", err) | ||||||
| 		} | 		} | ||||||
| 		certBundle, err = parsedCertBundle.ToCertBundle() | 		certBundle, err = parsedCertBundle.ToCertBundle() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return newdbplugin.InitializeResponse{}, errwrap.Wrapf("Error marshaling PEM information: {{err}}", err) | 			return dbplugin.InitializeResponse{}, errwrap.Wrapf("Error marshaling PEM information: {{err}}", err) | ||||||
| 		} | 		} | ||||||
| 		c.certificate = certBundle.Certificate | 		c.certificate = certBundle.Certificate | ||||||
| 		c.privateKey = certBundle.PrivateKey | 		c.privateKey = certBundle.PrivateKey | ||||||
| @@ -108,11 +107,11 @@ func (c *cassandraConnectionProducer) Initialize(ctx context.Context, req newdbp | |||||||
| 	case len(c.PemBundle) != 0: | 	case len(c.PemBundle) != 0: | ||||||
| 		parsedCertBundle, err = certutil.ParsePEMBundle(c.PemBundle) | 		parsedCertBundle, err = certutil.ParsePEMBundle(c.PemBundle) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return newdbplugin.InitializeResponse{}, errwrap.Wrapf("Error parsing the given PEM information: {{err}}", err) | 			return dbplugin.InitializeResponse{}, errwrap.Wrapf("Error parsing the given PEM information: {{err}}", err) | ||||||
| 		} | 		} | ||||||
| 		certBundle, err = parsedCertBundle.ToCertBundle() | 		certBundle, err = parsedCertBundle.ToCertBundle() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return newdbplugin.InitializeResponse{}, errwrap.Wrapf("Error marshaling PEM information: {{err}}", err) | 			return dbplugin.InitializeResponse{}, errwrap.Wrapf("Error marshaling PEM information: {{err}}", err) | ||||||
| 		} | 		} | ||||||
| 		c.certificate = certBundle.Certificate | 		c.certificate = certBundle.Certificate | ||||||
| 		c.privateKey = certBundle.PrivateKey | 		c.privateKey = certBundle.PrivateKey | ||||||
| @@ -126,11 +125,11 @@ func (c *cassandraConnectionProducer) Initialize(ctx context.Context, req newdbp | |||||||
|  |  | ||||||
| 	if req.VerifyConnection { | 	if req.VerifyConnection { | ||||||
| 		if _, err := c.Connection(ctx); err != nil { | 		if _, err := c.Connection(ctx); err != nil { | ||||||
| 			return newdbplugin.InitializeResponse{}, errwrap.Wrapf("error verifying connection: {{err}}", err) | 			return dbplugin.InitializeResponse{}, errwrap.Wrapf("error verifying connection: {{err}}", err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	resp := newdbplugin.InitializeResponse{ | 	resp := dbplugin.InitializeResponse{ | ||||||
| 		Config: req.Config, | 		Config: req.Config, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,8 +8,8 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/errwrap" | 	"github.com/hashicorp/errwrap" | ||||||
|  | 	dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/connutil" | 	"github.com/hashicorp/vault/sdk/database/helper/connutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" |  | ||||||
| 	"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" | ||||||
| @@ -43,7 +43,7 @@ type influxdbConnectionProducer struct { | |||||||
| 	sync.Mutex | 	sync.Mutex | ||||||
| } | } | ||||||
|  |  | ||||||
| func (i *influxdbConnectionProducer) Initialize(ctx context.Context, req newdbplugin.InitializeRequest) (newdbplugin.InitializeResponse, error) { | func (i *influxdbConnectionProducer) Initialize(ctx context.Context, req dbplugin.InitializeRequest) (dbplugin.InitializeResponse, error) { | ||||||
| 	i.Lock() | 	i.Lock() | ||||||
| 	defer i.Unlock() | 	defer i.Unlock() | ||||||
|  |  | ||||||
| @@ -51,7 +51,7 @@ func (i *influxdbConnectionProducer) Initialize(ctx context.Context, req newdbpl | |||||||
|  |  | ||||||
| 	err := mapstructure.WeakDecode(req.Config, i) | 	err := mapstructure.WeakDecode(req.Config, i) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.InitializeResponse{}, err | 		return dbplugin.InitializeResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if i.ConnectTimeoutRaw == nil { | 	if i.ConnectTimeoutRaw == nil { | ||||||
| @@ -62,16 +62,16 @@ func (i *influxdbConnectionProducer) Initialize(ctx context.Context, req newdbpl | |||||||
| 	} | 	} | ||||||
| 	i.connectTimeout, err = parseutil.ParseDurationSecond(i.ConnectTimeoutRaw) | 	i.connectTimeout, err = parseutil.ParseDurationSecond(i.ConnectTimeoutRaw) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.InitializeResponse{}, errwrap.Wrapf("invalid connect_timeout: {{err}}", err) | 		return dbplugin.InitializeResponse{}, errwrap.Wrapf("invalid connect_timeout: {{err}}", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	switch { | 	switch { | ||||||
| 	case len(i.Host) == 0: | 	case len(i.Host) == 0: | ||||||
| 		return newdbplugin.InitializeResponse{}, fmt.Errorf("host cannot be empty") | 		return dbplugin.InitializeResponse{}, fmt.Errorf("host cannot be empty") | ||||||
| 	case len(i.Username) == 0: | 	case len(i.Username) == 0: | ||||||
| 		return newdbplugin.InitializeResponse{}, fmt.Errorf("username cannot be empty") | 		return dbplugin.InitializeResponse{}, fmt.Errorf("username cannot be empty") | ||||||
| 	case len(i.Password) == 0: | 	case len(i.Password) == 0: | ||||||
| 		return newdbplugin.InitializeResponse{}, fmt.Errorf("password cannot be empty") | 		return dbplugin.InitializeResponse{}, fmt.Errorf("password cannot be empty") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var certBundle *certutil.CertBundle | 	var certBundle *certutil.CertBundle | ||||||
| @@ -80,11 +80,11 @@ func (i *influxdbConnectionProducer) Initialize(ctx context.Context, req newdbpl | |||||||
| 	case len(i.PemJSON) != 0: | 	case len(i.PemJSON) != 0: | ||||||
| 		parsedCertBundle, err = certutil.ParsePKIJSON([]byte(i.PemJSON)) | 		parsedCertBundle, err = certutil.ParsePKIJSON([]byte(i.PemJSON)) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return newdbplugin.InitializeResponse{}, errwrap.Wrapf("could not parse given JSON; it must be in the format of the output of the PKI backend certificate issuing command: {{err}}", err) | 			return dbplugin.InitializeResponse{}, errwrap.Wrapf("could not parse given JSON; it must be in the format of the output of the PKI backend certificate issuing command: {{err}}", err) | ||||||
| 		} | 		} | ||||||
| 		certBundle, err = parsedCertBundle.ToCertBundle() | 		certBundle, err = parsedCertBundle.ToCertBundle() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return newdbplugin.InitializeResponse{}, errwrap.Wrapf("Error marshaling PEM information: {{err}}", err) | 			return dbplugin.InitializeResponse{}, errwrap.Wrapf("Error marshaling PEM information: {{err}}", err) | ||||||
| 		} | 		} | ||||||
| 		i.certificate = certBundle.Certificate | 		i.certificate = certBundle.Certificate | ||||||
| 		i.privateKey = certBundle.PrivateKey | 		i.privateKey = certBundle.PrivateKey | ||||||
| @@ -94,11 +94,11 @@ func (i *influxdbConnectionProducer) Initialize(ctx context.Context, req newdbpl | |||||||
| 	case len(i.PemBundle) != 0: | 	case len(i.PemBundle) != 0: | ||||||
| 		parsedCertBundle, err = certutil.ParsePEMBundle(i.PemBundle) | 		parsedCertBundle, err = certutil.ParsePEMBundle(i.PemBundle) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return newdbplugin.InitializeResponse{}, errwrap.Wrapf("Error parsing the given PEM information: {{err}}", err) | 			return dbplugin.InitializeResponse{}, errwrap.Wrapf("Error parsing the given PEM information: {{err}}", err) | ||||||
| 		} | 		} | ||||||
| 		certBundle, err = parsedCertBundle.ToCertBundle() | 		certBundle, err = parsedCertBundle.ToCertBundle() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return newdbplugin.InitializeResponse{}, errwrap.Wrapf("Error marshaling PEM information: {{err}}", err) | 			return dbplugin.InitializeResponse{}, errwrap.Wrapf("Error marshaling PEM information: {{err}}", err) | ||||||
| 		} | 		} | ||||||
| 		i.certificate = certBundle.Certificate | 		i.certificate = certBundle.Certificate | ||||||
| 		i.privateKey = certBundle.PrivateKey | 		i.privateKey = certBundle.PrivateKey | ||||||
| @@ -112,11 +112,11 @@ func (i *influxdbConnectionProducer) Initialize(ctx context.Context, req newdbpl | |||||||
|  |  | ||||||
| 	if req.VerifyConnection { | 	if req.VerifyConnection { | ||||||
| 		if _, err := i.Connection(ctx); err != nil { | 		if _, err := i.Connection(ctx); err != nil { | ||||||
| 			return newdbplugin.InitializeResponse{}, errwrap.Wrapf("error verifying connection: {{err}}", err) | 			return dbplugin.InitializeResponse{}, errwrap.Wrapf("error verifying connection: {{err}}", err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	resp := newdbplugin.InitializeResponse{ | 	resp := dbplugin.InitializeResponse{ | ||||||
| 		Config: req.Config, | 		Config: req.Config, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,12 +5,11 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/credsutil" |  | ||||||
|  |  | ||||||
| 	multierror "github.com/hashicorp/go-multierror" | 	multierror "github.com/hashicorp/go-multierror" | ||||||
| 	"github.com/hashicorp/vault/api" | 	"github.com/hashicorp/vault/api" | ||||||
|  | 	dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/database/helper/credsutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" |  | ||||||
| 	"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" | ||||||
| ) | ) | ||||||
| @@ -22,7 +21,7 @@ const ( | |||||||
| 	influxdbTypeName                  = "influxdb" | 	influxdbTypeName                  = "influxdb" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var _ newdbplugin.Database = &Influxdb{} | var _ dbplugin.Database = &Influxdb{} | ||||||
|  |  | ||||||
| // Influxdb is an implementation of Database interface | // Influxdb is an implementation of Database interface | ||||||
| type Influxdb struct { | type Influxdb struct { | ||||||
| @@ -32,7 +31,7 @@ type Influxdb struct { | |||||||
| // New returns a new Cassandra instance | // New returns a new Cassandra instance | ||||||
| func New() (interface{}, error) { | func New() (interface{}, error) { | ||||||
| 	db := new() | 	db := new() | ||||||
| 	dbType := newdbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) | 	dbType := dbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) | ||||||
|  |  | ||||||
| 	return dbType, nil | 	return dbType, nil | ||||||
| } | } | ||||||
| @@ -53,7 +52,7 @@ func Run(apiTLSConfig *api.TLSConfig) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	newdbplugin.Serve(dbType.(newdbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | 	dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -74,13 +73,13 @@ func (i *Influxdb) getConnection(ctx context.Context) (influx.Client, error) { | |||||||
|  |  | ||||||
| // NewUser generates the username/password on the underlying Influxdb secret backend as instructed by | // NewUser generates the username/password on the underlying Influxdb secret backend as instructed by | ||||||
| // the statements provided. | // the statements provided. | ||||||
| func (i *Influxdb) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) (resp newdbplugin.NewUserResponse, err error) { | func (i *Influxdb) NewUser(ctx context.Context, req dbplugin.NewUserRequest) (resp dbplugin.NewUserResponse, err error) { | ||||||
| 	i.Lock() | 	i.Lock() | ||||||
| 	defer i.Unlock() | 	defer i.Unlock() | ||||||
|  |  | ||||||
| 	cli, err := i.getConnection(ctx) | 	cli, err := i.getConnection(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, fmt.Errorf("unable to get connection: %w", err) | 		return dbplugin.NewUserResponse{}, fmt.Errorf("unable to get connection: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	creationIFQL := req.Statements.Commands | 	creationIFQL := req.Statements.Commands | ||||||
| @@ -101,7 +100,7 @@ func (i *Influxdb) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) | |||||||
| 		credsutil.ToLower(), | 		credsutil.ToLower(), | ||||||
| 	) | 	) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, fmt.Errorf("failed to generate username: %w", err) | 		return dbplugin.NewUserResponse{}, fmt.Errorf("failed to generate username: %w", err) | ||||||
| 	} | 	} | ||||||
| 	username = strings.Replace(username, "-", "_", -1) | 	username = strings.Replace(username, "-", "_", -1) | ||||||
|  |  | ||||||
| @@ -122,11 +121,11 @@ func (i *Influxdb) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) | |||||||
| 				if response != nil && response.Error() != nil { | 				if response != nil && response.Error() != nil { | ||||||
| 					attemptRollback(cli, username, rollbackIFQL) | 					attemptRollback(cli, username, rollbackIFQL) | ||||||
| 				} | 				} | ||||||
| 				return newdbplugin.NewUserResponse{}, fmt.Errorf("failed to run query in InfluxDB: %w", err) | 				return dbplugin.NewUserResponse{}, fmt.Errorf("failed to run query in InfluxDB: %w", err) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	resp = newdbplugin.NewUserResponse{ | 	resp = dbplugin.NewUserResponse{ | ||||||
| 		Username: username, | 		Username: username, | ||||||
| 	} | 	} | ||||||
| 	return resp, nil | 	return resp, nil | ||||||
| @@ -157,13 +156,13 @@ func attemptRollback(cli influx.Client, username string, rollbackStatements []st | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (i *Influxdb) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserRequest) (newdbplugin.DeleteUserResponse, error) { | func (i *Influxdb) DeleteUser(ctx context.Context, req dbplugin.DeleteUserRequest) (dbplugin.DeleteUserResponse, error) { | ||||||
| 	i.Lock() | 	i.Lock() | ||||||
| 	defer i.Unlock() | 	defer i.Unlock() | ||||||
|  |  | ||||||
| 	cli, err := i.getConnection(ctx) | 	cli, err := i.getConnection(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.DeleteUserResponse{}, fmt.Errorf("unable to get connection: %w", err) | 		return dbplugin.DeleteUserResponse{}, fmt.Errorf("unable to get connection: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	revocationIFQL := req.Statements.Commands | 	revocationIFQL := req.Statements.Commands | ||||||
| @@ -190,14 +189,14 @@ func (i *Influxdb) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserReq | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if result.ErrorOrNil() != nil { | 	if result.ErrorOrNil() != nil { | ||||||
| 		return newdbplugin.DeleteUserResponse{}, fmt.Errorf("failed to delete user cleanly: %w", result.ErrorOrNil()) | 		return dbplugin.DeleteUserResponse{}, fmt.Errorf("failed to delete user cleanly: %w", result.ErrorOrNil()) | ||||||
| 	} | 	} | ||||||
| 	return newdbplugin.DeleteUserResponse{}, nil | 	return dbplugin.DeleteUserResponse{}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (i *Influxdb) UpdateUser(ctx context.Context, req newdbplugin.UpdateUserRequest) (newdbplugin.UpdateUserResponse, error) { | func (i *Influxdb) UpdateUser(ctx context.Context, req dbplugin.UpdateUserRequest) (dbplugin.UpdateUserResponse, error) { | ||||||
| 	if req.Password == nil && req.Expiration == nil { | 	if req.Password == nil && req.Expiration == nil { | ||||||
| 		return newdbplugin.UpdateUserResponse{}, fmt.Errorf("no changes requested") | 		return dbplugin.UpdateUserResponse{}, fmt.Errorf("no changes requested") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	i.Lock() | 	i.Lock() | ||||||
| @@ -206,14 +205,14 @@ func (i *Influxdb) UpdateUser(ctx context.Context, req newdbplugin.UpdateUserReq | |||||||
| 	if req.Password != nil { | 	if req.Password != nil { | ||||||
| 		err := i.changeUserPassword(ctx, req.Username, req.Password) | 		err := i.changeUserPassword(ctx, req.Username, req.Password) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return newdbplugin.UpdateUserResponse{}, fmt.Errorf("failed to change %q password: %w", req.Username, err) | 			return dbplugin.UpdateUserResponse{}, fmt.Errorf("failed to change %q password: %w", req.Username, err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	// Expiration is a no-op | 	// Expiration is a no-op | ||||||
| 	return newdbplugin.UpdateUserResponse{}, nil | 	return dbplugin.UpdateUserResponse{}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (i *Influxdb) changeUserPassword(ctx context.Context, username string, changePassword *newdbplugin.ChangePassword) error { | func (i *Influxdb) changeUserPassword(ctx context.Context, username string, changePassword *dbplugin.ChangePassword) error { | ||||||
| 	cli, err := i.getConnection(ctx) | 	cli, err := i.getConnection(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("unable to get connection: %w", err) | 		return fmt.Errorf("unable to get connection: %w", err) | ||||||
|   | |||||||
| @@ -11,12 +11,10 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" |  | ||||||
|  |  | ||||||
| 	dbtesting "github.com/hashicorp/vault/sdk/database/newdbplugin/testing" |  | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/errwrap" | 	"github.com/hashicorp/errwrap" | ||||||
| 	"github.com/hashicorp/vault/helper/testhelpers/docker" | 	"github.com/hashicorp/vault/helper/testhelpers/docker" | ||||||
|  | 	dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
|  | 	dbtesting "github.com/hashicorp/vault/sdk/database/dbplugin/v5/testing" | ||||||
| 	influx "github.com/influxdata/influxdb/client/v2" | 	influx "github.com/influxdata/influxdb/client/v2" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -101,78 +99,78 @@ func TestInfluxdb_Initialize(t *testing.T) { | |||||||
| 	defer cleanup() | 	defer cleanup() | ||||||
|  |  | ||||||
| 	type testCase struct { | 	type testCase struct { | ||||||
| 		req               newdbplugin.InitializeRequest | 		req               dbplugin.InitializeRequest | ||||||
| 		expectedResponse  newdbplugin.InitializeResponse | 		expectedResponse  dbplugin.InitializeResponse | ||||||
| 		expectErr         bool | 		expectErr         bool | ||||||
| 		expectInitialized bool | 		expectInitialized bool | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tests := map[string]testCase{ | 	tests := map[string]testCase{ | ||||||
| 		"port is an int": { | 		"port is an int": { | ||||||
| 			req: newdbplugin.InitializeRequest{ | 			req: dbplugin.InitializeRequest{ | ||||||
| 				Config:           makeConfig(config.connectionParams()), | 				Config:           makeConfig(config.connectionParams()), | ||||||
| 				VerifyConnection: true, | 				VerifyConnection: true, | ||||||
| 			}, | 			}, | ||||||
| 			expectedResponse: newdbplugin.InitializeResponse{ | 			expectedResponse: dbplugin.InitializeResponse{ | ||||||
| 				Config: config.connectionParams(), | 				Config: config.connectionParams(), | ||||||
| 			}, | 			}, | ||||||
| 			expectErr:         false, | 			expectErr:         false, | ||||||
| 			expectInitialized: true, | 			expectInitialized: true, | ||||||
| 		}, | 		}, | ||||||
| 		"port is a string": { | 		"port is a string": { | ||||||
| 			req: newdbplugin.InitializeRequest{ | 			req: dbplugin.InitializeRequest{ | ||||||
| 				Config:           makeConfig(config.connectionParams(), "port", strconv.Itoa(config.connectionParams()["port"].(int))), | 				Config:           makeConfig(config.connectionParams(), "port", strconv.Itoa(config.connectionParams()["port"].(int))), | ||||||
| 				VerifyConnection: true, | 				VerifyConnection: true, | ||||||
| 			}, | 			}, | ||||||
| 			expectedResponse: newdbplugin.InitializeResponse{ | 			expectedResponse: dbplugin.InitializeResponse{ | ||||||
| 				Config: makeConfig(config.connectionParams(), "port", strconv.Itoa(config.connectionParams()["port"].(int))), | 				Config: makeConfig(config.connectionParams(), "port", strconv.Itoa(config.connectionParams()["port"].(int))), | ||||||
| 			}, | 			}, | ||||||
| 			expectErr:         false, | 			expectErr:         false, | ||||||
| 			expectInitialized: true, | 			expectInitialized: true, | ||||||
| 		}, | 		}, | ||||||
| 		"missing config": { | 		"missing config": { | ||||||
| 			req: newdbplugin.InitializeRequest{ | 			req: dbplugin.InitializeRequest{ | ||||||
| 				Config:           nil, | 				Config:           nil, | ||||||
| 				VerifyConnection: true, | 				VerifyConnection: true, | ||||||
| 			}, | 			}, | ||||||
| 			expectedResponse:  newdbplugin.InitializeResponse{}, | 			expectedResponse:  dbplugin.InitializeResponse{}, | ||||||
| 			expectErr:         true, | 			expectErr:         true, | ||||||
| 			expectInitialized: false, | 			expectInitialized: false, | ||||||
| 		}, | 		}, | ||||||
| 		"missing host": { | 		"missing host": { | ||||||
| 			req: newdbplugin.InitializeRequest{ | 			req: dbplugin.InitializeRequest{ | ||||||
| 				Config:           makeConfig(config.connectionParams(), "host", ""), | 				Config:           makeConfig(config.connectionParams(), "host", ""), | ||||||
| 				VerifyConnection: true, | 				VerifyConnection: true, | ||||||
| 			}, | 			}, | ||||||
| 			expectedResponse:  newdbplugin.InitializeResponse{}, | 			expectedResponse:  dbplugin.InitializeResponse{}, | ||||||
| 			expectErr:         true, | 			expectErr:         true, | ||||||
| 			expectInitialized: false, | 			expectInitialized: false, | ||||||
| 		}, | 		}, | ||||||
| 		"missing username": { | 		"missing username": { | ||||||
| 			req: newdbplugin.InitializeRequest{ | 			req: dbplugin.InitializeRequest{ | ||||||
| 				Config:           makeConfig(config.connectionParams(), "username", ""), | 				Config:           makeConfig(config.connectionParams(), "username", ""), | ||||||
| 				VerifyConnection: true, | 				VerifyConnection: true, | ||||||
| 			}, | 			}, | ||||||
| 			expectedResponse:  newdbplugin.InitializeResponse{}, | 			expectedResponse:  dbplugin.InitializeResponse{}, | ||||||
| 			expectErr:         true, | 			expectErr:         true, | ||||||
| 			expectInitialized: false, | 			expectInitialized: false, | ||||||
| 		}, | 		}, | ||||||
| 		"missing password": { | 		"missing password": { | ||||||
| 			req: newdbplugin.InitializeRequest{ | 			req: dbplugin.InitializeRequest{ | ||||||
| 				Config:           makeConfig(config.connectionParams(), "password", ""), | 				Config:           makeConfig(config.connectionParams(), "password", ""), | ||||||
| 				VerifyConnection: true, | 				VerifyConnection: true, | ||||||
| 			}, | 			}, | ||||||
| 			expectedResponse:  newdbplugin.InitializeResponse{}, | 			expectedResponse:  dbplugin.InitializeResponse{}, | ||||||
| 			expectErr:         true, | 			expectErr:         true, | ||||||
| 			expectInitialized: false, | 			expectInitialized: false, | ||||||
| 		}, | 		}, | ||||||
| 		"failed to validate connection": { | 		"failed to validate connection": { | ||||||
| 			req: newdbplugin.InitializeRequest{ | 			req: dbplugin.InitializeRequest{ | ||||||
| 				// Host exists, but isn't a running instance | 				// Host exists, but isn't a running instance | ||||||
| 				Config:           makeConfig(config.connectionParams(), "host", "foobar://bad_connection"), | 				Config:           makeConfig(config.connectionParams(), "host", "foobar://bad_connection"), | ||||||
| 				VerifyConnection: true, | 				VerifyConnection: true, | ||||||
| 			}, | 			}, | ||||||
| 			expectedResponse:  newdbplugin.InitializeResponse{}, | 			expectedResponse:  dbplugin.InitializeResponse{}, | ||||||
| 			expectErr:         true, | 			expectErr:         true, | ||||||
| 			expectInitialized: true, | 			expectInitialized: true, | ||||||
| 		}, | 		}, | ||||||
| @@ -227,19 +225,19 @@ func TestInfluxdb_CreateUser(t *testing.T) { | |||||||
| 	defer cleanup() | 	defer cleanup() | ||||||
|  |  | ||||||
| 	db := new() | 	db := new() | ||||||
| 	req := newdbplugin.InitializeRequest{ | 	req := dbplugin.InitializeRequest{ | ||||||
| 		Config:           config.connectionParams(), | 		Config:           config.connectionParams(), | ||||||
| 		VerifyConnection: true, | 		VerifyConnection: true, | ||||||
| 	} | 	} | ||||||
| 	dbtesting.AssertInitialize(t, db, req) | 	dbtesting.AssertInitialize(t, db, req) | ||||||
|  |  | ||||||
| 	password := "nuozxby98523u89bdfnkjl" | 	password := "nuozxby98523u89bdfnkjl" | ||||||
| 	newUserReq := newdbplugin.NewUserRequest{ | 	newUserReq := dbplugin.NewUserRequest{ | ||||||
| 		UsernameConfig: newdbplugin.UsernameMetadata{ | 		UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 			DisplayName: "test", | 			DisplayName: "test", | ||||||
| 			RoleName:    "test", | 			RoleName:    "test", | ||||||
| 		}, | 		}, | ||||||
| 		Statements: newdbplugin.Statements{ | 		Statements: dbplugin.Statements{ | ||||||
| 			Commands: []string{createUserStatements}, | 			Commands: []string{createUserStatements}, | ||||||
| 		}, | 		}, | ||||||
| 		Password:   password, | 		Password:   password, | ||||||
| @@ -261,19 +259,19 @@ func TestUpdateUser_expiration(t *testing.T) { | |||||||
| 	defer cleanup() | 	defer cleanup() | ||||||
|  |  | ||||||
| 	db := new() | 	db := new() | ||||||
| 	req := newdbplugin.InitializeRequest{ | 	req := dbplugin.InitializeRequest{ | ||||||
| 		Config:           config.connectionParams(), | 		Config:           config.connectionParams(), | ||||||
| 		VerifyConnection: true, | 		VerifyConnection: true, | ||||||
| 	} | 	} | ||||||
| 	dbtesting.AssertInitialize(t, db, req) | 	dbtesting.AssertInitialize(t, db, req) | ||||||
|  |  | ||||||
| 	password := "nuozxby98523u89bdfnkjl" | 	password := "nuozxby98523u89bdfnkjl" | ||||||
| 	newUserReq := newdbplugin.NewUserRequest{ | 	newUserReq := dbplugin.NewUserRequest{ | ||||||
| 		UsernameConfig: newdbplugin.UsernameMetadata{ | 		UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 			DisplayName: "test", | 			DisplayName: "test", | ||||||
| 			RoleName:    "test", | 			RoleName:    "test", | ||||||
| 		}, | 		}, | ||||||
| 		Statements: newdbplugin.Statements{ | 		Statements: dbplugin.Statements{ | ||||||
| 			Commands: []string{createUserStatements}, | 			Commands: []string{createUserStatements}, | ||||||
| 		}, | 		}, | ||||||
| 		Password:   password, | 		Password:   password, | ||||||
| @@ -283,9 +281,9 @@ func TestUpdateUser_expiration(t *testing.T) { | |||||||
|  |  | ||||||
| 	assertCredsExist(t, config.URL().String(), newUserResp.Username, password) | 	assertCredsExist(t, config.URL().String(), newUserResp.Username, password) | ||||||
|  |  | ||||||
| 	renewReq := newdbplugin.UpdateUserRequest{ | 	renewReq := dbplugin.UpdateUserRequest{ | ||||||
| 		Username: newUserResp.Username, | 		Username: newUserResp.Username, | ||||||
| 		Expiration: &newdbplugin.ChangeExpiration{ | 		Expiration: &dbplugin.ChangeExpiration{ | ||||||
| 			NewExpiration: time.Now().Add(5 * time.Minute), | 			NewExpiration: time.Now().Add(5 * time.Minute), | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| @@ -300,19 +298,19 @@ func TestUpdateUser_password(t *testing.T) { | |||||||
| 	defer cleanup() | 	defer cleanup() | ||||||
|  |  | ||||||
| 	db := new() | 	db := new() | ||||||
| 	req := newdbplugin.InitializeRequest{ | 	req := dbplugin.InitializeRequest{ | ||||||
| 		Config:           config.connectionParams(), | 		Config:           config.connectionParams(), | ||||||
| 		VerifyConnection: true, | 		VerifyConnection: true, | ||||||
| 	} | 	} | ||||||
| 	dbtesting.AssertInitialize(t, db, req) | 	dbtesting.AssertInitialize(t, db, req) | ||||||
|  |  | ||||||
| 	initialPassword := "nuozxby98523u89bdfnkjl" | 	initialPassword := "nuozxby98523u89bdfnkjl" | ||||||
| 	newUserReq := newdbplugin.NewUserRequest{ | 	newUserReq := dbplugin.NewUserRequest{ | ||||||
| 		UsernameConfig: newdbplugin.UsernameMetadata{ | 		UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 			DisplayName: "test", | 			DisplayName: "test", | ||||||
| 			RoleName:    "test", | 			RoleName:    "test", | ||||||
| 		}, | 		}, | ||||||
| 		Statements: newdbplugin.Statements{ | 		Statements: dbplugin.Statements{ | ||||||
| 			Commands: []string{createUserStatements}, | 			Commands: []string{createUserStatements}, | ||||||
| 		}, | 		}, | ||||||
| 		Password:   initialPassword, | 		Password:   initialPassword, | ||||||
| @@ -323,9 +321,9 @@ func TestUpdateUser_password(t *testing.T) { | |||||||
| 	assertCredsExist(t, config.URL().String(), newUserResp.Username, initialPassword) | 	assertCredsExist(t, config.URL().String(), newUserResp.Username, initialPassword) | ||||||
|  |  | ||||||
| 	newPassword := "y89qgmbzadiygry8uazodijnb" | 	newPassword := "y89qgmbzadiygry8uazodijnb" | ||||||
| 	newPasswordReq := newdbplugin.UpdateUserRequest{ | 	newPasswordReq := dbplugin.UpdateUserRequest{ | ||||||
| 		Username: newUserResp.Username, | 		Username: newUserResp.Username, | ||||||
| 		Password: &newdbplugin.ChangePassword{ | 		Password: &dbplugin.ChangePassword{ | ||||||
| 			NewPassword: newPassword, | 			NewPassword: newPassword, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| @@ -346,14 +344,14 @@ func TestInfluxdb_RevokeDeletedUser(t *testing.T) { | |||||||
| 	defer cleanup() | 	defer cleanup() | ||||||
|  |  | ||||||
| 	db := new() | 	db := new() | ||||||
| 	req := newdbplugin.InitializeRequest{ | 	req := dbplugin.InitializeRequest{ | ||||||
| 		Config:           config.connectionParams(), | 		Config:           config.connectionParams(), | ||||||
| 		VerifyConnection: true, | 		VerifyConnection: true, | ||||||
| 	} | 	} | ||||||
| 	dbtesting.AssertInitialize(t, db, req) | 	dbtesting.AssertInitialize(t, db, req) | ||||||
|  |  | ||||||
| 	// attempt to revoke a user that does not exist | 	// attempt to revoke a user that does not exist | ||||||
| 	delReq := newdbplugin.DeleteUserRequest{ | 	delReq := dbplugin.DeleteUserRequest{ | ||||||
| 		Username: "someuser", | 		Username: "someuser", | ||||||
| 	} | 	} | ||||||
| 	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) | 	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) | ||||||
| @@ -369,19 +367,19 @@ func TestInfluxdb_RevokeUser(t *testing.T) { | |||||||
| 	defer cleanup() | 	defer cleanup() | ||||||
|  |  | ||||||
| 	db := new() | 	db := new() | ||||||
| 	req := newdbplugin.InitializeRequest{ | 	req := dbplugin.InitializeRequest{ | ||||||
| 		Config:           config.connectionParams(), | 		Config:           config.connectionParams(), | ||||||
| 		VerifyConnection: true, | 		VerifyConnection: true, | ||||||
| 	} | 	} | ||||||
| 	dbtesting.AssertInitialize(t, db, req) | 	dbtesting.AssertInitialize(t, db, req) | ||||||
|  |  | ||||||
| 	initialPassword := "nuozxby98523u89bdfnkjl" | 	initialPassword := "nuozxby98523u89bdfnkjl" | ||||||
| 	newUserReq := newdbplugin.NewUserRequest{ | 	newUserReq := dbplugin.NewUserRequest{ | ||||||
| 		UsernameConfig: newdbplugin.UsernameMetadata{ | 		UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 			DisplayName: "test", | 			DisplayName: "test", | ||||||
| 			RoleName:    "test", | 			RoleName:    "test", | ||||||
| 		}, | 		}, | ||||||
| 		Statements: newdbplugin.Statements{ | 		Statements: dbplugin.Statements{ | ||||||
| 			Commands: []string{createUserStatements}, | 			Commands: []string{createUserStatements}, | ||||||
| 		}, | 		}, | ||||||
| 		Password:   initialPassword, | 		Password:   initialPassword, | ||||||
| @@ -391,7 +389,7 @@ func TestInfluxdb_RevokeUser(t *testing.T) { | |||||||
|  |  | ||||||
| 	assertCredsExist(t, config.URL().String(), newUserResp.Username, initialPassword) | 	assertCredsExist(t, config.URL().String(), newUserResp.Username, initialPassword) | ||||||
|  |  | ||||||
| 	delReq := newdbplugin.DeleteUserRequest{ | 	delReq := dbplugin.DeleteUserRequest{ | ||||||
| 		Username: newUserResp.Username, | 		Username: newUserResp.Username, | ||||||
| 	} | 	} | ||||||
| 	dbtesting.AssertDeleteUser(t, db, delReq) | 	dbtesting.AssertDeleteUser(t, db, delReq) | ||||||
|   | |||||||
| @@ -10,10 +10,9 @@ import ( | |||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/errwrap" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/connutil" | 	"github.com/hashicorp/vault/sdk/database/helper/connutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/errwrap" |  | ||||||
| 	"go.mongodb.org/mongo-driver/mongo" | 	"go.mongodb.org/mongo-driver/mongo" | ||||||
| 	"go.mongodb.org/mongo-driver/mongo/options" | 	"go.mongodb.org/mongo-driver/mongo/options" | ||||||
| 	"go.mongodb.org/mongo-driver/mongo/readpref" | 	"go.mongodb.org/mongo-driver/mongo/readpref" | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/helper/testhelpers/certhelpers" | 	"github.com/hashicorp/vault/helper/testhelpers/certhelpers" | ||||||
| 	"github.com/hashicorp/vault/helper/testhelpers/mongodb" | 	"github.com/hashicorp/vault/helper/testhelpers/mongodb" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/ory/dockertest" | 	"github.com/ory/dockertest" | ||||||
| 	"go.mongodb.org/mongo-driver/mongo" | 	"go.mongodb.org/mongo-driver/mongo" | ||||||
| 	"go.mongodb.org/mongo-driver/mongo/options" | 	"go.mongodb.org/mongo-driver/mongo/options" | ||||||
| @@ -79,7 +79,7 @@ net: | |||||||
| 	// Test | 	// Test | ||||||
| 	mongo := new() | 	mongo := new() | ||||||
|  |  | ||||||
| 	initReq := newdbplugin.InitializeRequest{ | 	initReq := dbplugin.InitializeRequest{ | ||||||
| 		Config: map[string]interface{}{ | 		Config: map[string]interface{}{ | ||||||
| 			"connection_url":      retURL, | 			"connection_url":      retURL, | ||||||
| 			"allowed_roles":       "*", | 			"allowed_roles":       "*", | ||||||
|   | |||||||
| @@ -8,9 +8,9 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/api" | 	"github.com/hashicorp/vault/api" | ||||||
|  | 	dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/credsutil" | 	"github.com/hashicorp/vault/sdk/database/helper/credsutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" |  | ||||||
| 	"github.com/mitchellh/mapstructure" | 	"github.com/mitchellh/mapstructure" | ||||||
| 	"go.mongodb.org/mongo-driver/mongo" | 	"go.mongodb.org/mongo-driver/mongo" | ||||||
| 	"go.mongodb.org/mongo-driver/mongo/options" | 	"go.mongodb.org/mongo-driver/mongo/options" | ||||||
| @@ -26,12 +26,12 @@ type MongoDB struct { | |||||||
| 	*mongoDBConnectionProducer | 	*mongoDBConnectionProducer | ||||||
| } | } | ||||||
|  |  | ||||||
| var _ newdbplugin.Database = &MongoDB{} | var _ dbplugin.Database = &MongoDB{} | ||||||
|  |  | ||||||
| // New returns a new MongoDB instance | // New returns a new MongoDB instance | ||||||
| func New() (interface{}, error) { | func New() (interface{}, error) { | ||||||
| 	db := new() | 	db := new() | ||||||
| 	dbType := newdbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) | 	dbType := dbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) | ||||||
| 	return dbType, nil | 	return dbType, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -52,7 +52,7 @@ func Run(apiTLSConfig *api.TLSConfig) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	newdbplugin.Serve(dbType.(newdbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | 	dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -71,7 +71,7 @@ func (m *MongoDB) getConnection(ctx context.Context) (*mongo.Client, error) { | |||||||
| 	return client.(*mongo.Client), nil | 	return client.(*mongo.Client), nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MongoDB) Initialize(ctx context.Context, req newdbplugin.InitializeRequest) (newdbplugin.InitializeResponse, error) { | func (m *MongoDB) Initialize(ctx context.Context, req dbplugin.InitializeRequest) (dbplugin.InitializeResponse, error) { | ||||||
| 	m.Lock() | 	m.Lock() | ||||||
| 	defer m.Unlock() | 	defer m.Unlock() | ||||||
|  |  | ||||||
| @@ -79,21 +79,21 @@ func (m *MongoDB) Initialize(ctx context.Context, req newdbplugin.InitializeRequ | |||||||
|  |  | ||||||
| 	err := mapstructure.WeakDecode(req.Config, m.mongoDBConnectionProducer) | 	err := mapstructure.WeakDecode(req.Config, m.mongoDBConnectionProducer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.InitializeResponse{}, err | 		return dbplugin.InitializeResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(m.ConnectionURL) == 0 { | 	if len(m.ConnectionURL) == 0 { | ||||||
| 		return newdbplugin.InitializeResponse{}, fmt.Errorf("connection_url cannot be empty-mongo fail") | 		return dbplugin.InitializeResponse{}, fmt.Errorf("connection_url cannot be empty-mongo fail") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	writeOpts, err := m.getWriteConcern() | 	writeOpts, err := m.getWriteConcern() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.InitializeResponse{}, err | 		return dbplugin.InitializeResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	authOpts, err := m.getTLSAuth() | 	authOpts, err := m.getTLSAuth() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.InitializeResponse{}, err | 		return dbplugin.InitializeResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	m.clientOptions = options.MergeClientOptions(writeOpts, authOpts) | 	m.clientOptions = options.MergeClientOptions(writeOpts, authOpts) | ||||||
| @@ -105,28 +105,28 @@ func (m *MongoDB) Initialize(ctx context.Context, req newdbplugin.InitializeRequ | |||||||
| 	if req.VerifyConnection { | 	if req.VerifyConnection { | ||||||
| 		_, err := m.Connection(ctx) | 		_, err := m.Connection(ctx) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return newdbplugin.InitializeResponse{}, fmt.Errorf("failed to verify connection: %w", err) | 			return dbplugin.InitializeResponse{}, fmt.Errorf("failed to verify connection: %w", err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		err = m.client.Ping(ctx, readpref.Primary()) | 		err = m.client.Ping(ctx, readpref.Primary()) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return newdbplugin.InitializeResponse{}, fmt.Errorf("failed to verify connection: %w", err) | 			return dbplugin.InitializeResponse{}, fmt.Errorf("failed to verify connection: %w", err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	resp := newdbplugin.InitializeResponse{ | 	resp := dbplugin.InitializeResponse{ | ||||||
| 		Config: req.Config, | 		Config: req.Config, | ||||||
| 	} | 	} | ||||||
| 	return resp, nil | 	return resp, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MongoDB) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) (newdbplugin.NewUserResponse, error) { | func (m *MongoDB) NewUser(ctx context.Context, req dbplugin.NewUserRequest) (dbplugin.NewUserResponse, error) { | ||||||
| 	// Grab the lock | 	// Grab the lock | ||||||
| 	m.Lock() | 	m.Lock() | ||||||
| 	defer m.Unlock() | 	defer m.Unlock() | ||||||
|  |  | ||||||
| 	if len(req.Statements.Commands) == 0 { | 	if len(req.Statements.Commands) == 0 { | ||||||
| 		return newdbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement | 		return dbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	username, err := credsutil.GenerateUsername( | 	username, err := credsutil.GenerateUsername( | ||||||
| @@ -136,14 +136,14 @@ func (m *MongoDB) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) ( | |||||||
| 		credsutil.Separator("-"), | 		credsutil.Separator("-"), | ||||||
| 	) | 	) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, err | 		return dbplugin.NewUserResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Unmarshal statements.CreationStatements into mongodbRoles | 	// Unmarshal statements.CreationStatements into mongodbRoles | ||||||
| 	var mongoCS mongoDBStatement | 	var mongoCS mongoDBStatement | ||||||
| 	err = json.Unmarshal([]byte(req.Statements.Commands[0]), &mongoCS) | 	err = json.Unmarshal([]byte(req.Statements.Commands[0]), &mongoCS) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, err | 		return dbplugin.NewUserResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Default to "admin" if no db provided | 	// Default to "admin" if no db provided | ||||||
| @@ -152,7 +152,7 @@ func (m *MongoDB) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) ( | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(mongoCS.Roles) == 0 { | 	if len(mongoCS.Roles) == 0 { | ||||||
| 		return newdbplugin.NewUserResponse{}, fmt.Errorf("roles array is required in creation statement") | 		return dbplugin.NewUserResponse{}, fmt.Errorf("roles array is required in creation statement") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	createUserCmd := createUserCommand{ | 	createUserCmd := createUserCommand{ | ||||||
| @@ -162,21 +162,21 @@ func (m *MongoDB) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) ( | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := m.runCommandWithRetry(ctx, mongoCS.DB, createUserCmd); err != nil { | 	if err := m.runCommandWithRetry(ctx, mongoCS.DB, createUserCmd); err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, err | 		return dbplugin.NewUserResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	resp := newdbplugin.NewUserResponse{ | 	resp := dbplugin.NewUserResponse{ | ||||||
| 		Username: username, | 		Username: username, | ||||||
| 	} | 	} | ||||||
| 	return resp, nil | 	return resp, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MongoDB) UpdateUser(ctx context.Context, req newdbplugin.UpdateUserRequest) (newdbplugin.UpdateUserResponse, error) { | func (m *MongoDB) UpdateUser(ctx context.Context, req dbplugin.UpdateUserRequest) (dbplugin.UpdateUserResponse, error) { | ||||||
| 	if req.Password != nil { | 	if req.Password != nil { | ||||||
| 		err := m.changeUserPassword(ctx, req.Username, req.Password.NewPassword) | 		err := m.changeUserPassword(ctx, req.Username, req.Password.NewPassword) | ||||||
| 		return newdbplugin.UpdateUserResponse{}, err | 		return dbplugin.UpdateUserResponse{}, err | ||||||
| 	} | 	} | ||||||
| 	return newdbplugin.UpdateUserResponse{}, nil | 	return dbplugin.UpdateUserResponse{}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MongoDB) changeUserPassword(ctx context.Context, username, password string) error { | func (m *MongoDB) changeUserPassword(ctx context.Context, username, password string) error { | ||||||
| @@ -208,7 +208,7 @@ func (m *MongoDB) changeUserPassword(ctx context.Context, username, password str | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MongoDB) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserRequest) (newdbplugin.DeleteUserResponse, error) { | func (m *MongoDB) DeleteUser(ctx context.Context, req dbplugin.DeleteUserRequest) (dbplugin.DeleteUserResponse, error) { | ||||||
| 	m.Lock() | 	m.Lock() | ||||||
| 	defer m.Unlock() | 	defer m.Unlock() | ||||||
|  |  | ||||||
| @@ -220,14 +220,14 @@ func (m *MongoDB) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserRequ | |||||||
| 	case 1: | 	case 1: | ||||||
| 		revocationStatement = req.Statements.Commands[0] | 		revocationStatement = req.Statements.Commands[0] | ||||||
| 	default: | 	default: | ||||||
| 		return newdbplugin.DeleteUserResponse{}, fmt.Errorf("expected 0 or 1 revocation statements, got %d", len(req.Statements.Commands)) | 		return dbplugin.DeleteUserResponse{}, fmt.Errorf("expected 0 or 1 revocation statements, got %d", len(req.Statements.Commands)) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Unmarshal revocation statements into mongodbRoles | 	// Unmarshal revocation statements into mongodbRoles | ||||||
| 	var mongoCS mongoDBStatement | 	var mongoCS mongoDBStatement | ||||||
| 	err := json.Unmarshal([]byte(revocationStatement), &mongoCS) | 	err := json.Unmarshal([]byte(revocationStatement), &mongoCS) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.DeleteUserResponse{}, err | 		return dbplugin.DeleteUserResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	db := mongoCS.DB | 	db := mongoCS.DB | ||||||
| @@ -242,7 +242,7 @@ func (m *MongoDB) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserRequ | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err = m.runCommandWithRetry(ctx, db, dropUserCmd) | 	err = m.runCommandWithRetry(ctx, db, dropUserCmd) | ||||||
| 	return newdbplugin.DeleteUserResponse{}, err | 	return dbplugin.DeleteUserResponse{}, err | ||||||
| } | } | ||||||
|  |  | ||||||
| // runCommandWithRetry runs a command and retries once more if there's a failure | // runCommandWithRetry runs a command and retries once more if there's a failure | ||||||
|   | |||||||
| @@ -12,8 +12,8 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/helper/testhelpers/certhelpers" | 	"github.com/hashicorp/vault/helper/testhelpers/certhelpers" | ||||||
| 	"github.com/hashicorp/vault/helper/testhelpers/mongodb" | 	"github.com/hashicorp/vault/helper/testhelpers/mongodb" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	dbtesting "github.com/hashicorp/vault/sdk/database/newdbplugin/testing" | 	dbtesting "github.com/hashicorp/vault/sdk/database/dbplugin/v5/testing" | ||||||
| 	"go.mongodb.org/mongo-driver/mongo" | 	"go.mongodb.org/mongo-driver/mongo" | ||||||
| 	"go.mongodb.org/mongo-driver/mongo/options" | 	"go.mongodb.org/mongo-driver/mongo/options" | ||||||
| 	"go.mongodb.org/mongo-driver/mongo/readpref" | 	"go.mongodb.org/mongo-driver/mongo/readpref" | ||||||
| @@ -35,7 +35,7 @@ func TestMongoDB_Initialize(t *testing.T) { | |||||||
| 	// Make a copy since the original map could be modified by the Initialize call | 	// Make a copy since the original map could be modified by the Initialize call | ||||||
| 	expectedConfig := copyConfig(config) | 	expectedConfig := copyConfig(config) | ||||||
|  |  | ||||||
| 	req := newdbplugin.InitializeRequest{ | 	req := dbplugin.InitializeRequest{ | ||||||
| 		Config:           config, | 		Config:           config, | ||||||
| 		VerifyConnection: true, | 		VerifyConnection: true, | ||||||
| 	} | 	} | ||||||
| @@ -58,7 +58,7 @@ func TestMongoDB_CreateUser(t *testing.T) { | |||||||
| 	db := new() | 	db := new() | ||||||
| 	defer dbtesting.AssertClose(t, db) | 	defer dbtesting.AssertClose(t, db) | ||||||
|  |  | ||||||
| 	initReq := newdbplugin.InitializeRequest{ | 	initReq := dbplugin.InitializeRequest{ | ||||||
| 		Config: map[string]interface{}{ | 		Config: map[string]interface{}{ | ||||||
| 			"connection_url": connURL, | 			"connection_url": connURL, | ||||||
| 		}, | 		}, | ||||||
| @@ -67,12 +67,12 @@ func TestMongoDB_CreateUser(t *testing.T) { | |||||||
| 	dbtesting.AssertInitialize(t, db, initReq) | 	dbtesting.AssertInitialize(t, db, initReq) | ||||||
|  |  | ||||||
| 	password := "myreallysecurepassword" | 	password := "myreallysecurepassword" | ||||||
| 	createReq := newdbplugin.NewUserRequest{ | 	createReq := dbplugin.NewUserRequest{ | ||||||
| 		UsernameConfig: newdbplugin.UsernameMetadata{ | 		UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 			DisplayName: "test", | 			DisplayName: "test", | ||||||
| 			RoleName:    "test", | 			RoleName:    "test", | ||||||
| 		}, | 		}, | ||||||
| 		Statements: newdbplugin.Statements{ | 		Statements: dbplugin.Statements{ | ||||||
| 			Commands: []string{mongoAdminRole}, | 			Commands: []string{mongoAdminRole}, | ||||||
| 		}, | 		}, | ||||||
| 		Password:   password, | 		Password:   password, | ||||||
| @@ -87,7 +87,7 @@ func TestMongoDB_CreateUser_writeConcern(t *testing.T) { | |||||||
| 	cleanup, connURL := mongodb.PrepareTestContainer(t, "latest") | 	cleanup, connURL := mongodb.PrepareTestContainer(t, "latest") | ||||||
| 	defer cleanup() | 	defer cleanup() | ||||||
|  |  | ||||||
| 	initReq := newdbplugin.InitializeRequest{ | 	initReq := dbplugin.InitializeRequest{ | ||||||
| 		Config: map[string]interface{}{ | 		Config: map[string]interface{}{ | ||||||
| 			"connection_url": connURL, | 			"connection_url": connURL, | ||||||
| 			"write_concern":  `{ "wmode": "majority", "wtimeout": 5000 }`, | 			"write_concern":  `{ "wmode": "majority", "wtimeout": 5000 }`, | ||||||
| @@ -101,12 +101,12 @@ func TestMongoDB_CreateUser_writeConcern(t *testing.T) { | |||||||
| 	dbtesting.AssertInitialize(t, db, initReq) | 	dbtesting.AssertInitialize(t, db, initReq) | ||||||
|  |  | ||||||
| 	password := "myreallysecurepassword" | 	password := "myreallysecurepassword" | ||||||
| 	createReq := newdbplugin.NewUserRequest{ | 	createReq := dbplugin.NewUserRequest{ | ||||||
| 		UsernameConfig: newdbplugin.UsernameMetadata{ | 		UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 			DisplayName: "test", | 			DisplayName: "test", | ||||||
| 			RoleName:    "test", | 			RoleName:    "test", | ||||||
| 		}, | 		}, | ||||||
| 		Statements: newdbplugin.Statements{ | 		Statements: dbplugin.Statements{ | ||||||
| 			Commands: []string{mongoAdminRole}, | 			Commands: []string{mongoAdminRole}, | ||||||
| 		}, | 		}, | ||||||
| 		Password:   password, | 		Password:   password, | ||||||
| @@ -124,7 +124,7 @@ func TestMongoDB_DeleteUser(t *testing.T) { | |||||||
| 	db := new() | 	db := new() | ||||||
| 	defer dbtesting.AssertClose(t, db) | 	defer dbtesting.AssertClose(t, db) | ||||||
|  |  | ||||||
| 	initReq := newdbplugin.InitializeRequest{ | 	initReq := dbplugin.InitializeRequest{ | ||||||
| 		Config: map[string]interface{}{ | 		Config: map[string]interface{}{ | ||||||
| 			"connection_url": connURL, | 			"connection_url": connURL, | ||||||
| 		}, | 		}, | ||||||
| @@ -133,12 +133,12 @@ func TestMongoDB_DeleteUser(t *testing.T) { | |||||||
| 	dbtesting.AssertInitialize(t, db, initReq) | 	dbtesting.AssertInitialize(t, db, initReq) | ||||||
|  |  | ||||||
| 	password := "myreallysecurepassword" | 	password := "myreallysecurepassword" | ||||||
| 	createReq := newdbplugin.NewUserRequest{ | 	createReq := dbplugin.NewUserRequest{ | ||||||
| 		UsernameConfig: newdbplugin.UsernameMetadata{ | 		UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 			DisplayName: "test", | 			DisplayName: "test", | ||||||
| 			RoleName:    "test", | 			RoleName:    "test", | ||||||
| 		}, | 		}, | ||||||
| 		Statements: newdbplugin.Statements{ | 		Statements: dbplugin.Statements{ | ||||||
| 			Commands: []string{mongoAdminRole}, | 			Commands: []string{mongoAdminRole}, | ||||||
| 		}, | 		}, | ||||||
| 		Password:   password, | 		Password:   password, | ||||||
| @@ -148,7 +148,7 @@ func TestMongoDB_DeleteUser(t *testing.T) { | |||||||
| 	assertCredsExist(t, createResp.Username, password, connURL) | 	assertCredsExist(t, createResp.Username, password, connURL) | ||||||
|  |  | ||||||
| 	// Test default revocation statement | 	// Test default revocation statement | ||||||
| 	delReq := newdbplugin.DeleteUserRequest{ | 	delReq := dbplugin.DeleteUserRequest{ | ||||||
| 		Username: createResp.Username, | 		Username: createResp.Username, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -167,7 +167,7 @@ func TestMongoDB_UpdateUser_Password(t *testing.T) { | |||||||
| 	db := new() | 	db := new() | ||||||
| 	defer dbtesting.AssertClose(t, db) | 	defer dbtesting.AssertClose(t, db) | ||||||
|  |  | ||||||
| 	initReq := newdbplugin.InitializeRequest{ | 	initReq := dbplugin.InitializeRequest{ | ||||||
| 		Config: map[string]interface{}{ | 		Config: map[string]interface{}{ | ||||||
| 			"connection_url": connURL, | 			"connection_url": connURL, | ||||||
| 		}, | 		}, | ||||||
| @@ -182,9 +182,9 @@ func TestMongoDB_UpdateUser_Password(t *testing.T) { | |||||||
|  |  | ||||||
| 	newPassword := "myreallysecurecredentials" | 	newPassword := "myreallysecurecredentials" | ||||||
|  |  | ||||||
| 	updateReq := newdbplugin.UpdateUserRequest{ | 	updateReq := dbplugin.UpdateUserRequest{ | ||||||
| 		Username: dbUser, | 		Username: dbUser, | ||||||
| 		Password: &newdbplugin.ChangePassword{ | 		Password: &dbplugin.ChangePassword{ | ||||||
| 			NewPassword: newPassword, | 			NewPassword: newPassword, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -11,17 +11,17 @@ 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" | ||||||
|  | 	dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/connutil" | 	"github.com/hashicorp/vault/sdk/database/helper/connutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/credsutil" | 	"github.com/hashicorp/vault/sdk/database/helper/credsutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" |  | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/dbtxn" | 	"github.com/hashicorp/vault/sdk/helper/dbtxn" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/strutil" | 	"github.com/hashicorp/vault/sdk/helper/strutil" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const msSQLTypeName = "mssql" | const msSQLTypeName = "mssql" | ||||||
|  |  | ||||||
| var _ newdbplugin.Database = &MSSQL{} | var _ dbplugin.Database = &MSSQL{} | ||||||
|  |  | ||||||
| // MSSQL is an implementation of Database interface | // MSSQL is an implementation of Database interface | ||||||
| type MSSQL struct { | type MSSQL struct { | ||||||
| @@ -31,7 +31,7 @@ type MSSQL struct { | |||||||
| func New() (interface{}, error) { | func New() (interface{}, error) { | ||||||
| 	db := new() | 	db := new() | ||||||
| 	// Wrap the plugin with middleware to sanitize errors | 	// Wrap the plugin with middleware to sanitize errors | ||||||
| 	dbType := newdbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) | 	dbType := dbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) | ||||||
|  |  | ||||||
| 	return dbType, nil | 	return dbType, nil | ||||||
| } | } | ||||||
| @@ -52,7 +52,7 @@ func Run(apiTLSConfig *api.TLSConfig) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	newdbplugin.Serve(dbType.(newdbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | 	dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -77,12 +77,12 @@ func (m *MSSQL) getConnection(ctx context.Context) (*sql.DB, error) { | |||||||
| 	return db.(*sql.DB), nil | 	return db.(*sql.DB), nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MSSQL) Initialize(ctx context.Context, req newdbplugin.InitializeRequest) (newdbplugin.InitializeResponse, error) { | func (m *MSSQL) Initialize(ctx context.Context, req dbplugin.InitializeRequest) (dbplugin.InitializeResponse, error) { | ||||||
| 	newConf, err := m.SQLConnectionProducer.Init(ctx, req.Config, req.VerifyConnection) | 	newConf, err := m.SQLConnectionProducer.Init(ctx, req.Config, req.VerifyConnection) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.InitializeResponse{}, err | 		return dbplugin.InitializeResponse{}, err | ||||||
| 	} | 	} | ||||||
| 	resp := newdbplugin.InitializeResponse{ | 	resp := dbplugin.InitializeResponse{ | ||||||
| 		Config: newConf, | 		Config: newConf, | ||||||
| 	} | 	} | ||||||
| 	return resp, nil | 	return resp, nil | ||||||
| @@ -90,17 +90,17 @@ func (m *MSSQL) Initialize(ctx context.Context, req newdbplugin.InitializeReques | |||||||
|  |  | ||||||
| // NewUser generates the username/password on the underlying MSSQL secret backend as instructed by | // NewUser generates the username/password on the underlying MSSQL secret backend as instructed by | ||||||
| // the statements provided. | // the statements provided. | ||||||
| func (m *MSSQL) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) (newdbplugin.NewUserResponse, error) { | func (m *MSSQL) NewUser(ctx context.Context, req dbplugin.NewUserRequest) (dbplugin.NewUserResponse, error) { | ||||||
| 	m.Lock() | 	m.Lock() | ||||||
| 	defer m.Unlock() | 	defer m.Unlock() | ||||||
|  |  | ||||||
| 	db, err := m.getConnection(ctx) | 	db, err := m.getConnection(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, fmt.Errorf("unable to get connection: %w", err) | 		return dbplugin.NewUserResponse{}, fmt.Errorf("unable to get connection: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(req.Statements.Commands) == 0 { | 	if len(req.Statements.Commands) == 0 { | ||||||
| 		return newdbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement | 		return dbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	username, err := credsutil.GenerateUsername( | 	username, err := credsutil.GenerateUsername( | ||||||
| @@ -110,14 +110,14 @@ func (m *MSSQL) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) (ne | |||||||
| 		credsutil.Separator("-"), | 		credsutil.Separator("-"), | ||||||
| 	) | 	) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, err | 		return dbplugin.NewUserResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expirationStr := req.Expiration.Format("2006-01-02 15:04:05-0700") | 	expirationStr := req.Expiration.Format("2006-01-02 15:04:05-0700") | ||||||
|  |  | ||||||
| 	tx, err := db.BeginTx(ctx, nil) | 	tx, err := db.BeginTx(ctx, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, err | 		return dbplugin.NewUserResponse{}, err | ||||||
| 	} | 	} | ||||||
| 	defer tx.Rollback() | 	defer tx.Rollback() | ||||||
|  |  | ||||||
| @@ -135,16 +135,16 @@ func (m *MSSQL) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) (ne | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if err := dbtxn.ExecuteTxQuery(ctx, tx, m, query); err != nil { | 			if err := dbtxn.ExecuteTxQuery(ctx, tx, m, query); err != nil { | ||||||
| 				return newdbplugin.NewUserResponse{}, err | 				return dbplugin.NewUserResponse{}, err | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := tx.Commit(); err != nil { | 	if err := tx.Commit(); err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, err | 		return dbplugin.NewUserResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	resp := newdbplugin.NewUserResponse{ | 	resp := dbplugin.NewUserResponse{ | ||||||
| 		Username: username, | 		Username: username, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -154,15 +154,15 @@ func (m *MSSQL) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) (ne | |||||||
| // DeleteUser attempts to drop the specified user. It will first attempt to disable login, | // DeleteUser 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 | // then kill pending connections from that user, and finally drop the user and login from the | ||||||
| // database instance. | // database instance. | ||||||
| func (m *MSSQL) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserRequest) (newdbplugin.DeleteUserResponse, error) { | func (m *MSSQL) DeleteUser(ctx context.Context, req dbplugin.DeleteUserRequest) (dbplugin.DeleteUserResponse, error) { | ||||||
| 	if len(req.Statements.Commands) == 0 { | 	if len(req.Statements.Commands) == 0 { | ||||||
| 		err := m.revokeUserDefault(ctx, req.Username) | 		err := m.revokeUserDefault(ctx, req.Username) | ||||||
| 		return newdbplugin.DeleteUserResponse{}, err | 		return dbplugin.DeleteUserResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	db, err := m.getConnection(ctx) | 	db, err := m.getConnection(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.DeleteUserResponse{}, fmt.Errorf("unable to get connection: %w", err) | 		return dbplugin.DeleteUserResponse{}, fmt.Errorf("unable to get connection: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	merr := &multierror.Error{} | 	merr := &multierror.Error{} | ||||||
| @@ -184,7 +184,7 @@ func (m *MSSQL) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserReques | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return newdbplugin.DeleteUserResponse{}, merr.ErrorOrNil() | 	return dbplugin.DeleteUserResponse{}, merr.ErrorOrNil() | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MSSQL) revokeUserDefault(ctx context.Context, username string) error { | func (m *MSSQL) revokeUserDefault(ctx context.Context, username string) error { | ||||||
| @@ -290,19 +290,19 @@ func (m *MSSQL) revokeUserDefault(ctx context.Context, username string) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MSSQL) UpdateUser(ctx context.Context, req newdbplugin.UpdateUserRequest) (newdbplugin.UpdateUserResponse, error) { | func (m *MSSQL) UpdateUser(ctx context.Context, req dbplugin.UpdateUserRequest) (dbplugin.UpdateUserResponse, error) { | ||||||
| 	if req.Password == nil && req.Expiration == nil { | 	if req.Password == nil && req.Expiration == nil { | ||||||
| 		return newdbplugin.UpdateUserResponse{}, fmt.Errorf("no changes requested") | 		return dbplugin.UpdateUserResponse{}, fmt.Errorf("no changes requested") | ||||||
| 	} | 	} | ||||||
| 	if req.Password != nil { | 	if req.Password != nil { | ||||||
| 		err := m.updateUserPass(ctx, req.Username, req.Password) | 		err := m.updateUserPass(ctx, req.Username, req.Password) | ||||||
| 		return newdbplugin.UpdateUserResponse{}, err | 		return dbplugin.UpdateUserResponse{}, err | ||||||
| 	} | 	} | ||||||
| 	// Expiration is a no-op | 	// Expiration is a no-op | ||||||
| 	return newdbplugin.UpdateUserResponse{}, nil | 	return dbplugin.UpdateUserResponse{}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MSSQL) updateUserPass(ctx context.Context, username string, changePass *newdbplugin.ChangePassword) error { | func (m *MSSQL) updateUserPass(ctx context.Context, username string, changePass *dbplugin.ChangePassword) error { | ||||||
| 	stmts := changePass.Statements.Commands | 	stmts := changePass.Statements.Commands | ||||||
| 	if len(stmts) == 0 { | 	if len(stmts) == 0 { | ||||||
| 		stmts = []string{alterLoginSQL} | 		stmts = []string{alterLoginSQL} | ||||||
|   | |||||||
| @@ -10,11 +10,10 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" |  | ||||||
| 	dbtesting "github.com/hashicorp/vault/sdk/database/newdbplugin/testing" |  | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/dbtxn" |  | ||||||
|  |  | ||||||
| 	mssqlhelper "github.com/hashicorp/vault/helper/testhelpers/mssql" | 	mssqlhelper "github.com/hashicorp/vault/helper/testhelpers/mssql" | ||||||
|  | 	dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
|  | 	dbtesting "github.com/hashicorp/vault/sdk/database/dbplugin/v5/testing" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/helper/dbtxn" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestInitialize(t *testing.T) { | func TestInitialize(t *testing.T) { | ||||||
| @@ -22,12 +21,12 @@ func TestInitialize(t *testing.T) { | |||||||
| 	defer cleanup() | 	defer cleanup() | ||||||
|  |  | ||||||
| 	type testCase struct { | 	type testCase struct { | ||||||
| 		req newdbplugin.InitializeRequest | 		req dbplugin.InitializeRequest | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tests := map[string]testCase{ | 	tests := map[string]testCase{ | ||||||
| 		"happy path": { | 		"happy path": { | ||||||
| 			req: newdbplugin.InitializeRequest{ | 			req: dbplugin.InitializeRequest{ | ||||||
| 				Config: map[string]interface{}{ | 				Config: map[string]interface{}{ | ||||||
| 					"connection_url": connURL, | 					"connection_url": connURL, | ||||||
| 				}, | 				}, | ||||||
| @@ -35,7 +34,7 @@ func TestInitialize(t *testing.T) { | |||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| 		"max_open_connections set": { | 		"max_open_connections set": { | ||||||
| 			newdbplugin.InitializeRequest{ | 			dbplugin.InitializeRequest{ | ||||||
| 				Config: map[string]interface{}{ | 				Config: map[string]interface{}{ | ||||||
| 					"connection_url":       connURL, | 					"connection_url":       connURL, | ||||||
| 					"max_open_connections": "5", | 					"max_open_connections": "5", | ||||||
| @@ -63,7 +62,7 @@ func TestNewUser(t *testing.T) { | |||||||
| 	defer cleanup() | 	defer cleanup() | ||||||
|  |  | ||||||
| 	type testCase struct { | 	type testCase struct { | ||||||
| 		req           newdbplugin.NewUserRequest | 		req           dbplugin.NewUserRequest | ||||||
| 		usernameRegex string | 		usernameRegex string | ||||||
| 		expectErr     bool | 		expectErr     bool | ||||||
| 		assertUser    func(t testing.TB, connURL, username, password string) | 		assertUser    func(t testing.TB, connURL, username, password string) | ||||||
| @@ -71,12 +70,12 @@ func TestNewUser(t *testing.T) { | |||||||
|  |  | ||||||
| 	tests := map[string]testCase{ | 	tests := map[string]testCase{ | ||||||
| 		"no creation statements": { | 		"no creation statements": { | ||||||
| 			req: newdbplugin.NewUserRequest{ | 			req: dbplugin.NewUserRequest{ | ||||||
| 				UsernameConfig: newdbplugin.UsernameMetadata{ | 				UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 					DisplayName: "test", | 					DisplayName: "test", | ||||||
| 					RoleName:    "test", | 					RoleName:    "test", | ||||||
| 				}, | 				}, | ||||||
| 				Statements: newdbplugin.Statements{}, | 				Statements: dbplugin.Statements{}, | ||||||
| 				Password:   "AG4qagho-dsvZ", | 				Password:   "AG4qagho-dsvZ", | ||||||
| 				Expiration: time.Now().Add(1 * time.Second), | 				Expiration: time.Now().Add(1 * time.Second), | ||||||
| 			}, | 			}, | ||||||
| @@ -85,12 +84,12 @@ func TestNewUser(t *testing.T) { | |||||||
| 			assertUser:    assertCredsDoNotExist, | 			assertUser:    assertCredsDoNotExist, | ||||||
| 		}, | 		}, | ||||||
| 		"with creation statements": { | 		"with creation statements": { | ||||||
| 			req: newdbplugin.NewUserRequest{ | 			req: dbplugin.NewUserRequest{ | ||||||
| 				UsernameConfig: newdbplugin.UsernameMetadata{ | 				UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 					DisplayName: "test", | 					DisplayName: "test", | ||||||
| 					RoleName:    "test", | 					RoleName:    "test", | ||||||
| 				}, | 				}, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: dbplugin.Statements{ | ||||||
| 					Commands: []string{testMSSQLRole}, | 					Commands: []string{testMSSQLRole}, | ||||||
| 				}, | 				}, | ||||||
| 				Password:   "AG4qagho-dsvZ", | 				Password:   "AG4qagho-dsvZ", | ||||||
| @@ -109,7 +108,7 @@ func TestNewUser(t *testing.T) { | |||||||
| 				t.Fatalf("failed to compile username regex %q: %s", test.usernameRegex, err) | 				t.Fatalf("failed to compile username regex %q: %s", test.usernameRegex, err) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			initReq := newdbplugin.InitializeRequest{ | 			initReq := dbplugin.InitializeRequest{ | ||||||
| 				Config: map[string]interface{}{ | 				Config: map[string]interface{}{ | ||||||
| 					"connection_url": connURL, | 					"connection_url": connURL, | ||||||
| 				}, | 				}, | ||||||
| @@ -133,7 +132,7 @@ func TestNewUser(t *testing.T) { | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			// Protect against future fields that aren't specified | 			// Protect against future fields that aren't specified | ||||||
| 			expectedResp := newdbplugin.NewUserResponse{ | 			expectedResp := dbplugin.NewUserResponse{ | ||||||
| 				Username: createResp.Username, | 				Username: createResp.Username, | ||||||
| 			} | 			} | ||||||
| 			if !reflect.DeepEqual(createResp, expectedResp) { | 			if !reflect.DeepEqual(createResp, expectedResp) { | ||||||
| @@ -147,7 +146,7 @@ func TestNewUser(t *testing.T) { | |||||||
|  |  | ||||||
| func TestUpdateUser_password(t *testing.T) { | func TestUpdateUser_password(t *testing.T) { | ||||||
| 	type testCase struct { | 	type testCase struct { | ||||||
| 		req              newdbplugin.UpdateUserRequest | 		req              dbplugin.UpdateUserRequest | ||||||
| 		expectErr        bool | 		expectErr        bool | ||||||
| 		expectedPassword string | 		expectedPassword string | ||||||
| 	} | 	} | ||||||
| @@ -157,33 +156,33 @@ func TestUpdateUser_password(t *testing.T) { | |||||||
|  |  | ||||||
| 	tests := map[string]testCase{ | 	tests := map[string]testCase{ | ||||||
| 		"missing password": { | 		"missing password": { | ||||||
| 			req: newdbplugin.UpdateUserRequest{ | 			req: dbplugin.UpdateUserRequest{ | ||||||
| 				Username: dbUser, | 				Username: dbUser, | ||||||
| 				Password: &newdbplugin.ChangePassword{ | 				Password: &dbplugin.ChangePassword{ | ||||||
| 					NewPassword: "", | 					NewPassword: "", | ||||||
| 					Statements:  newdbplugin.Statements{}, | 					Statements:  dbplugin.Statements{}, | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 			expectErr:        true, | 			expectErr:        true, | ||||||
| 			expectedPassword: initPassword, | 			expectedPassword: initPassword, | ||||||
| 		}, | 		}, | ||||||
| 		"empty rotation statements": { | 		"empty rotation statements": { | ||||||
| 			req: newdbplugin.UpdateUserRequest{ | 			req: dbplugin.UpdateUserRequest{ | ||||||
| 				Username: dbUser, | 				Username: dbUser, | ||||||
| 				Password: &newdbplugin.ChangePassword{ | 				Password: &dbplugin.ChangePassword{ | ||||||
| 					NewPassword: "N90gkKLy8$angf", | 					NewPassword: "N90gkKLy8$angf", | ||||||
| 					Statements:  newdbplugin.Statements{}, | 					Statements:  dbplugin.Statements{}, | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 			expectErr:        false, | 			expectErr:        false, | ||||||
| 			expectedPassword: "N90gkKLy8$angf", | 			expectedPassword: "N90gkKLy8$angf", | ||||||
| 		}, | 		}, | ||||||
| 		"username rotation": { | 		"username rotation": { | ||||||
| 			req: newdbplugin.UpdateUserRequest{ | 			req: dbplugin.UpdateUserRequest{ | ||||||
| 				Username: dbUser, | 				Username: dbUser, | ||||||
| 				Password: &newdbplugin.ChangePassword{ | 				Password: &dbplugin.ChangePassword{ | ||||||
| 					NewPassword: "N90gkKLy8$angf", | 					NewPassword: "N90gkKLy8$angf", | ||||||
| 					Statements: newdbplugin.Statements{ | 					Statements: dbplugin.Statements{ | ||||||
| 						Commands: []string{ | 						Commands: []string{ | ||||||
| 							"ALTER LOGIN [{{username}}] WITH PASSWORD = '{{password}}'", | 							"ALTER LOGIN [{{username}}] WITH PASSWORD = '{{password}}'", | ||||||
| 						}, | 						}, | ||||||
| @@ -194,11 +193,11 @@ func TestUpdateUser_password(t *testing.T) { | |||||||
| 			expectedPassword: "N90gkKLy8$angf", | 			expectedPassword: "N90gkKLy8$angf", | ||||||
| 		}, | 		}, | ||||||
| 		"bad statements": { | 		"bad statements": { | ||||||
| 			req: newdbplugin.UpdateUserRequest{ | 			req: dbplugin.UpdateUserRequest{ | ||||||
| 				Username: dbUser, | 				Username: dbUser, | ||||||
| 				Password: &newdbplugin.ChangePassword{ | 				Password: &dbplugin.ChangePassword{ | ||||||
| 					NewPassword: "N90gkKLy8$angf", | 					NewPassword: "N90gkKLy8$angf", | ||||||
| 					Statements: newdbplugin.Statements{ | 					Statements: dbplugin.Statements{ | ||||||
| 						Commands: []string{ | 						Commands: []string{ | ||||||
| 							"ahosh98asjdffs", | 							"ahosh98asjdffs", | ||||||
| 						}, | 						}, | ||||||
| @@ -215,7 +214,7 @@ func TestUpdateUser_password(t *testing.T) { | |||||||
| 			cleanup, connURL := mssqlhelper.PrepareMSSQLTestContainer(t) | 			cleanup, connURL := mssqlhelper.PrepareMSSQLTestContainer(t) | ||||||
| 			defer cleanup() | 			defer cleanup() | ||||||
|  |  | ||||||
| 			initReq := newdbplugin.InitializeRequest{ | 			initReq := dbplugin.InitializeRequest{ | ||||||
| 				Config: map[string]interface{}{ | 				Config: map[string]interface{}{ | ||||||
| 					"connection_url": connURL, | 					"connection_url": connURL, | ||||||
| 				}, | 				}, | ||||||
| @@ -241,7 +240,7 @@ func TestUpdateUser_password(t *testing.T) { | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			// Protect against future fields that aren't specified | 			// Protect against future fields that aren't specified | ||||||
| 			expectedResp := newdbplugin.UpdateUserResponse{} | 			expectedResp := dbplugin.UpdateUserResponse{} | ||||||
| 			if !reflect.DeepEqual(updateResp, expectedResp) { | 			if !reflect.DeepEqual(updateResp, expectedResp) { | ||||||
| 				t.Fatalf("Fields missing from expected response: Actual: %#v", updateResp) | 				t.Fatalf("Fields missing from expected response: Actual: %#v", updateResp) | ||||||
| 			} | 			} | ||||||
| @@ -258,7 +257,7 @@ func TestDeleteUser(t *testing.T) { | |||||||
| 	dbUser := "vaultuser" | 	dbUser := "vaultuser" | ||||||
| 	initPassword := "p4$sw0rd" | 	initPassword := "p4$sw0rd" | ||||||
|  |  | ||||||
| 	initReq := newdbplugin.InitializeRequest{ | 	initReq := dbplugin.InitializeRequest{ | ||||||
| 		Config: map[string]interface{}{ | 		Config: map[string]interface{}{ | ||||||
| 			"connection_url": connURL, | 			"connection_url": connURL, | ||||||
| 		}, | 		}, | ||||||
| @@ -273,7 +272,7 @@ func TestDeleteUser(t *testing.T) { | |||||||
|  |  | ||||||
| 	assertCredsExist(t, connURL, dbUser, initPassword) | 	assertCredsExist(t, connURL, dbUser, initPassword) | ||||||
|  |  | ||||||
| 	deleteReq := newdbplugin.DeleteUserRequest{ | 	deleteReq := dbplugin.DeleteUserRequest{ | ||||||
| 		Username: dbUser, | 		Username: dbUser, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -285,7 +284,7 @@ func TestDeleteUser(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Protect against future fields that aren't specified | 	// Protect against future fields that aren't specified | ||||||
| 	expectedResp := newdbplugin.DeleteUserResponse{} | 	expectedResp := dbplugin.DeleteUserResponse{} | ||||||
| 	if !reflect.DeepEqual(deleteResp, expectedResp) { | 	if !reflect.DeepEqual(deleteResp, expectedResp) { | ||||||
| 		t.Fatalf("Fields missing from expected response: Actual: %#v", deleteResp) | 		t.Fatalf("Fields missing from expected response: Actual: %#v", deleteResp) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -7,14 +7,13 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
|  | 	stdmysql "github.com/go-sql-driver/mysql" | ||||||
| 	"github.com/hashicorp/errwrap" | 	"github.com/hashicorp/errwrap" | ||||||
| 	"github.com/hashicorp/vault/api" | 	"github.com/hashicorp/vault/api" | ||||||
|  | 	dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/credsutil" | 	"github.com/hashicorp/vault/sdk/database/helper/credsutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" |  | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/strutil" | 	"github.com/hashicorp/vault/sdk/helper/strutil" | ||||||
|  |  | ||||||
| 	stdmysql "github.com/go-sql-driver/mysql" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| @@ -37,7 +36,7 @@ var ( | |||||||
| 	LegacyUsernameLen int = 16 | 	LegacyUsernameLen int = 16 | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var _ newdbplugin.Database = (*MySQL)(nil) | var _ dbplugin.Database = (*MySQL)(nil) | ||||||
|  |  | ||||||
| type MySQL struct { | type MySQL struct { | ||||||
| 	*mySQLConnectionProducer | 	*mySQLConnectionProducer | ||||||
| @@ -49,7 +48,7 @@ func New(legacy bool) func() (interface{}, error) { | |||||||
| 	return func() (interface{}, error) { | 	return func() (interface{}, error) { | ||||||
| 		db := new(legacy) | 		db := new(legacy) | ||||||
| 		// Wrap the plugin with middleware to sanitize errors | 		// Wrap the plugin with middleware to sanitize errors | ||||||
| 		dbType := newdbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.SecretValues) | 		dbType := dbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.SecretValues) | ||||||
|  |  | ||||||
| 		return dbType, nil | 		return dbType, nil | ||||||
| 	} | 	} | ||||||
| @@ -82,7 +81,7 @@ func runCommon(legacy bool, apiTLSConfig *api.TLSConfig) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	newdbplugin.Serve(dbType.(newdbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | 	dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -100,25 +99,25 @@ func (m *MySQL) getConnection(ctx context.Context) (*sql.DB, error) { | |||||||
| 	return db.(*sql.DB), nil | 	return db.(*sql.DB), nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MySQL) Initialize(ctx context.Context, req newdbplugin.InitializeRequest) (newdbplugin.InitializeResponse, error) { | func (m *MySQL) Initialize(ctx context.Context, req dbplugin.InitializeRequest) (dbplugin.InitializeResponse, error) { | ||||||
| 	err := m.mySQLConnectionProducer.Initialize(ctx, req.Config, req.VerifyConnection) | 	err := m.mySQLConnectionProducer.Initialize(ctx, req.Config, req.VerifyConnection) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.InitializeResponse{}, err | 		return dbplugin.InitializeResponse{}, err | ||||||
| 	} | 	} | ||||||
| 	resp := newdbplugin.InitializeResponse{ | 	resp := dbplugin.InitializeResponse{ | ||||||
| 		Config: req.Config, | 		Config: req.Config, | ||||||
| 	} | 	} | ||||||
| 	return resp, nil | 	return resp, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MySQL) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) (newdbplugin.NewUserResponse, error) { | func (m *MySQL) NewUser(ctx context.Context, req dbplugin.NewUserRequest) (dbplugin.NewUserResponse, error) { | ||||||
| 	if len(req.Statements.Commands) == 0 { | 	if len(req.Statements.Commands) == 0 { | ||||||
| 		return newdbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement | 		return dbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	username, err := m.generateUsername(req) | 	username, err := m.generateUsername(req) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, err | 		return dbplugin.NewUserResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	password := req.Password | 	password := req.Password | ||||||
| @@ -133,16 +132,16 @@ func (m *MySQL) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) (ne | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := m.executePreparedStatementsWithMap(ctx, req.Statements.Commands, queryMap); err != nil { | 	if err := m.executePreparedStatementsWithMap(ctx, req.Statements.Commands, queryMap); err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, err | 		return dbplugin.NewUserResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	resp := newdbplugin.NewUserResponse{ | 	resp := dbplugin.NewUserResponse{ | ||||||
| 		Username: username, | 		Username: username, | ||||||
| 	} | 	} | ||||||
| 	return resp, nil | 	return resp, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MySQL) generateUsername(req newdbplugin.NewUserRequest) (string, error) { | func (m *MySQL) generateUsername(req dbplugin.NewUserRequest) (string, error) { | ||||||
| 	var dispNameLen, roleNameLen, maxLen int | 	var dispNameLen, roleNameLen, maxLen int | ||||||
|  |  | ||||||
| 	if m.legacy { | 	if m.legacy { | ||||||
| @@ -167,7 +166,7 @@ func (m *MySQL) generateUsername(req newdbplugin.NewUserRequest) (string, error) | |||||||
| 	return username, nil | 	return username, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MySQL) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserRequest) (newdbplugin.DeleteUserResponse, error) { | func (m *MySQL) DeleteUser(ctx context.Context, req dbplugin.DeleteUserRequest) (dbplugin.DeleteUserResponse, error) { | ||||||
| 	// Grab the read lock | 	// Grab the read lock | ||||||
| 	m.Lock() | 	m.Lock() | ||||||
| 	defer m.Unlock() | 	defer m.Unlock() | ||||||
| @@ -175,7 +174,7 @@ func (m *MySQL) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserReques | |||||||
| 	// Get the connection | 	// Get the connection | ||||||
| 	db, err := m.getConnection(ctx) | 	db, err := m.getConnection(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.DeleteUserResponse{}, err | 		return dbplugin.DeleteUserResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	revocationStmts := req.Statements.Commands | 	revocationStmts := req.Statements.Commands | ||||||
| @@ -187,7 +186,7 @@ func (m *MySQL) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserReques | |||||||
| 	// Start a transaction | 	// Start a transaction | ||||||
| 	tx, err := db.BeginTx(ctx, nil) | 	tx, err := db.BeginTx(ctx, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.DeleteUserResponse{}, err | 		return dbplugin.DeleteUserResponse{}, err | ||||||
| 	} | 	} | ||||||
| 	defer tx.Rollback() | 	defer tx.Rollback() | ||||||
|  |  | ||||||
| @@ -205,31 +204,31 @@ func (m *MySQL) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserReques | |||||||
| 			query = strings.Replace(query, "{{username}}", req.Username, -1) | 			query = strings.Replace(query, "{{username}}", req.Username, -1) | ||||||
| 			_, err = tx.ExecContext(ctx, query) | 			_, err = tx.ExecContext(ctx, query) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return newdbplugin.DeleteUserResponse{}, err | 				return dbplugin.DeleteUserResponse{}, err | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Commit the transaction | 	// Commit the transaction | ||||||
| 	err = tx.Commit() | 	err = tx.Commit() | ||||||
| 	return newdbplugin.DeleteUserResponse{}, err | 	return dbplugin.DeleteUserResponse{}, err | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MySQL) UpdateUser(ctx context.Context, req newdbplugin.UpdateUserRequest) (newdbplugin.UpdateUserResponse, error) { | func (m *MySQL) UpdateUser(ctx context.Context, req dbplugin.UpdateUserRequest) (dbplugin.UpdateUserResponse, error) { | ||||||
| 	if req.Password == nil && req.Expiration == nil { | 	if req.Password == nil && req.Expiration == nil { | ||||||
| 		return newdbplugin.UpdateUserResponse{}, fmt.Errorf("no change requested") | 		return dbplugin.UpdateUserResponse{}, fmt.Errorf("no change requested") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if req.Password != nil { | 	if req.Password != nil { | ||||||
| 		err := m.changeUserPassword(ctx, req.Username, req.Password.NewPassword, req.Password.Statements.Commands) | 		err := m.changeUserPassword(ctx, req.Username, req.Password.NewPassword, req.Password.Statements.Commands) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return newdbplugin.UpdateUserResponse{}, fmt.Errorf("failed to change password: %w", err) | 			return dbplugin.UpdateUserResponse{}, fmt.Errorf("failed to change password: %w", err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Expiration change/update is currently a no-op | 	// Expiration change/update is currently a no-op | ||||||
|  |  | ||||||
| 	return newdbplugin.UpdateUserResponse{}, nil | 	return dbplugin.UpdateUserResponse{}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MySQL) changeUserPassword(ctx context.Context, username, password string, rotateStatements []string) error { | func (m *MySQL) changeUserPassword(ctx context.Context, username, password string, rotateStatements []string) error { | ||||||
|   | |||||||
| @@ -9,14 +9,13 @@ import ( | |||||||
|  |  | ||||||
| 	stdmysql "github.com/go-sql-driver/mysql" | 	stdmysql "github.com/go-sql-driver/mysql" | ||||||
| 	mysqlhelper "github.com/hashicorp/vault/helper/testhelpers/mysql" | 	mysqlhelper "github.com/hashicorp/vault/helper/testhelpers/mysql" | ||||||
|  | 	dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/credsutil" | 	"github.com/hashicorp/vault/sdk/database/helper/credsutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" |  | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/strutil" | 	"github.com/hashicorp/vault/sdk/helper/strutil" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var _ newdbplugin.Database = (*MySQL)(nil) | var _ dbplugin.Database = (*MySQL)(nil) | ||||||
|  |  | ||||||
| func TestMySQL_Initialize(t *testing.T) { | func TestMySQL_Initialize(t *testing.T) { | ||||||
| 	cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret") | 	cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret") | ||||||
| @@ -26,7 +25,7 @@ func TestMySQL_Initialize(t *testing.T) { | |||||||
| 		"connection_url": connURL, | 		"connection_url": connURL, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	initReq := newdbplugin.InitializeRequest{ | 	initReq := dbplugin.InitializeRequest{ | ||||||
| 		Config:           connectionDetails, | 		Config:           connectionDetails, | ||||||
| 		VerifyConnection: true, | 		VerifyConnection: true, | ||||||
| 	} | 	} | ||||||
| @@ -52,7 +51,7 @@ func TestMySQL_Initialize(t *testing.T) { | |||||||
| 		"max_open_connections": "5", | 		"max_open_connections": "5", | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	initReq = newdbplugin.InitializeRequest{ | 	initReq = dbplugin.InitializeRequest{ | ||||||
| 		Config:           connectionDetails, | 		Config:           connectionDetails, | ||||||
| 		VerifyConnection: true, | 		VerifyConnection: true, | ||||||
| 	} | 	} | ||||||
| @@ -73,12 +72,12 @@ func TestMySQL_CreateUser(t *testing.T) { | |||||||
| 			t.Fatalf("unable to generate password: %s", err) | 			t.Fatalf("unable to generate password: %s", err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		createReq := newdbplugin.NewUserRequest{ | 		createReq := dbplugin.NewUserRequest{ | ||||||
| 			UsernameConfig: newdbplugin.UsernameMetadata{ | 			UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 				DisplayName: "test", | 				DisplayName: "test", | ||||||
| 				RoleName:    "test", | 				RoleName:    "test", | ||||||
| 			}, | 			}, | ||||||
| 			Statements: newdbplugin.Statements{ | 			Statements: dbplugin.Statements{ | ||||||
| 				Commands: []string{}, | 				Commands: []string{}, | ||||||
| 			}, | 			}, | ||||||
| 			Password:   password, | 			Password:   password, | ||||||
| @@ -103,7 +102,7 @@ func TestMySQL_CreateUser(t *testing.T) { | |||||||
| 			"connection_url": connURL, | 			"connection_url": connURL, | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		initReq := newdbplugin.InitializeRequest{ | 		initReq := dbplugin.InitializeRequest{ | ||||||
| 			Config:           connectionDetails, | 			Config:           connectionDetails, | ||||||
| 			VerifyConnection: true, | 			VerifyConnection: true, | ||||||
| 		} | 		} | ||||||
| @@ -126,7 +125,7 @@ func TestMySQL_CreateUser(t *testing.T) { | |||||||
| 			"connection_url": connURL, | 			"connection_url": connURL, | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		initReq := newdbplugin.InitializeRequest{ | 		initReq := dbplugin.InitializeRequest{ | ||||||
| 			Config:           connectionDetails, | 			Config:           connectionDetails, | ||||||
| 			VerifyConnection: true, | 			VerifyConnection: true, | ||||||
| 		} | 		} | ||||||
| @@ -188,12 +187,12 @@ func testCreateUser(t *testing.T, db *MySQL, connURL string) { | |||||||
| 				t.Fatalf("unable to generate password: %s", err) | 				t.Fatalf("unable to generate password: %s", err) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			createReq := newdbplugin.NewUserRequest{ | 			createReq := dbplugin.NewUserRequest{ | ||||||
| 				UsernameConfig: newdbplugin.UsernameMetadata{ | 				UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 					DisplayName: "test", | 					DisplayName: "test", | ||||||
| 					RoleName:    "test", | 					RoleName:    "test", | ||||||
| 				}, | 				}, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: dbplugin.Statements{ | ||||||
| 					Commands: test.createStmts, | 					Commands: test.createStmts, | ||||||
| 				}, | 				}, | ||||||
| 				Password:   password, | 				Password:   password, | ||||||
| @@ -256,7 +255,7 @@ func TestMySQL_RotateRootCredentials(t *testing.T) { | |||||||
| 			ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) | 			ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) | ||||||
| 			defer cancel() | 			defer cancel() | ||||||
|  |  | ||||||
| 			initReq := newdbplugin.InitializeRequest{ | 			initReq := dbplugin.InitializeRequest{ | ||||||
| 				Config:           connectionDetails, | 				Config:           connectionDetails, | ||||||
| 				VerifyConnection: true, | 				VerifyConnection: true, | ||||||
| 			} | 			} | ||||||
| @@ -271,11 +270,11 @@ func TestMySQL_RotateRootCredentials(t *testing.T) { | |||||||
| 				t.Fatal("Database should be initialized") | 				t.Fatal("Database should be initialized") | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			updateReq := newdbplugin.UpdateUserRequest{ | 			updateReq := dbplugin.UpdateUserRequest{ | ||||||
| 				Username: "root", | 				Username: "root", | ||||||
| 				Password: &newdbplugin.ChangePassword{ | 				Password: &dbplugin.ChangePassword{ | ||||||
| 					NewPassword: "different_sercret", | 					NewPassword: "different_sercret", | ||||||
| 					Statements: newdbplugin.Statements{ | 					Statements: dbplugin.Statements{ | ||||||
| 						Commands: test.statements, | 						Commands: test.statements, | ||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
| @@ -331,7 +330,7 @@ func TestMySQL_DeleteUser(t *testing.T) { | |||||||
| 		"connection_url": connURL, | 		"connection_url": connURL, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	initReq := newdbplugin.InitializeRequest{ | 	initReq := dbplugin.InitializeRequest{ | ||||||
| 		Config:           connectionDetails, | 		Config:           connectionDetails, | ||||||
| 		VerifyConnection: true, | 		VerifyConnection: true, | ||||||
| 	} | 	} | ||||||
| @@ -349,12 +348,12 @@ func TestMySQL_DeleteUser(t *testing.T) { | |||||||
| 				t.Fatalf("unable to generate password: %s", err) | 				t.Fatalf("unable to generate password: %s", err) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			createReq := newdbplugin.NewUserRequest{ | 			createReq := dbplugin.NewUserRequest{ | ||||||
| 				UsernameConfig: newdbplugin.UsernameMetadata{ | 				UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 					DisplayName: "test", | 					DisplayName: "test", | ||||||
| 					RoleName:    "test", | 					RoleName:    "test", | ||||||
| 				}, | 				}, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: dbplugin.Statements{ | ||||||
| 					Commands: []string{` | 					Commands: []string{` | ||||||
| 						CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; | 						CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; | ||||||
| 						GRANT SELECT ON *.* TO '{{name}}'@'%';`, | 						GRANT SELECT ON *.* TO '{{name}}'@'%';`, | ||||||
| @@ -377,9 +376,9 @@ func TestMySQL_DeleteUser(t *testing.T) { | |||||||
| 				t.Fatalf("Could not connect with new credentials: %s", err) | 				t.Fatalf("Could not connect with new credentials: %s", err) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			deleteReq := newdbplugin.DeleteUserRequest{ | 			deleteReq := dbplugin.DeleteUserRequest{ | ||||||
| 				Username: userResp.Username, | 				Username: userResp.Username, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: dbplugin.Statements{ | ||||||
| 					Commands: test.revokeStmts, | 					Commands: test.revokeStmts, | ||||||
| 				}, | 				}, | ||||||
| 			} | 			} | ||||||
| @@ -436,7 +435,7 @@ func TestMySQL_UpdateUser(t *testing.T) { | |||||||
| 				"connection_url": connURL, | 				"connection_url": connURL, | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			initReq := newdbplugin.InitializeRequest{ | 			initReq := dbplugin.InitializeRequest{ | ||||||
| 				Config:           connectionDetails, | 				Config:           connectionDetails, | ||||||
| 				VerifyConnection: true, | 				VerifyConnection: true, | ||||||
| 			} | 			} | ||||||
| @@ -456,11 +455,11 @@ func TestMySQL_UpdateUser(t *testing.T) { | |||||||
| 				t.Fatalf("unable to generate password: %s", err) | 				t.Fatalf("unable to generate password: %s", err) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			updateReq := newdbplugin.UpdateUserRequest{ | 			updateReq := dbplugin.UpdateUserRequest{ | ||||||
| 				Username: dbUser, | 				Username: dbUser, | ||||||
| 				Password: &newdbplugin.ChangePassword{ | 				Password: &dbplugin.ChangePassword{ | ||||||
| 					NewPassword: newPassword, | 					NewPassword: newPassword, | ||||||
| 					Statements: newdbplugin.Statements{ | 					Statements: dbplugin.Statements{ | ||||||
| 						Commands: test.rotateStmts, | 						Commands: test.rotateStmts, | ||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
|   | |||||||
| @@ -10,10 +10,10 @@ import ( | |||||||
| 	"github.com/hashicorp/errwrap" | 	"github.com/hashicorp/errwrap" | ||||||
| 	"github.com/hashicorp/go-multierror" | 	"github.com/hashicorp/go-multierror" | ||||||
| 	"github.com/hashicorp/vault/api" | 	"github.com/hashicorp/vault/api" | ||||||
|  | 	dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/connutil" | 	"github.com/hashicorp/vault/sdk/database/helper/connutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/credsutil" | 	"github.com/hashicorp/vault/sdk/database/helper/credsutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | 	"github.com/hashicorp/vault/sdk/database/helper/dbutil" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" |  | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/dbtxn" | 	"github.com/hashicorp/vault/sdk/helper/dbtxn" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/strutil" | 	"github.com/hashicorp/vault/sdk/helper/strutil" | ||||||
| 	"github.com/lib/pq" | 	"github.com/lib/pq" | ||||||
| @@ -32,7 +32,7 @@ ALTER ROLE "{{username}}" WITH PASSWORD '{{password}}'; | |||||||
| ) | ) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| 	_ newdbplugin.Database = &PostgreSQL{} | 	_ dbplugin.Database = &PostgreSQL{} | ||||||
|  |  | ||||||
| 	// postgresEndStatement is basically the word "END" but | 	// postgresEndStatement is basically the word "END" but | ||||||
| 	// surrounded by a word boundary to differentiate it from | 	// surrounded by a word boundary to differentiate it from | ||||||
| @@ -52,7 +52,7 @@ var ( | |||||||
| func New() (interface{}, error) { | func New() (interface{}, error) { | ||||||
| 	db := new() | 	db := new() | ||||||
| 	// Wrap the plugin with middleware to sanitize errors | 	// Wrap the plugin with middleware to sanitize errors | ||||||
| 	dbType := newdbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) | 	dbType := dbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) | ||||||
| 	return dbType, nil | 	return dbType, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -74,7 +74,7 @@ func Run(apiTLSConfig *api.TLSConfig) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	newdbplugin.Serve(dbType.(newdbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | 	dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -83,12 +83,12 @@ type PostgreSQL struct { | |||||||
| 	*connutil.SQLConnectionProducer | 	*connutil.SQLConnectionProducer | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *PostgreSQL) Initialize(ctx context.Context, req newdbplugin.InitializeRequest) (newdbplugin.InitializeResponse, error) { | func (p *PostgreSQL) Initialize(ctx context.Context, req dbplugin.InitializeRequest) (dbplugin.InitializeResponse, error) { | ||||||
| 	newConf, err := p.SQLConnectionProducer.Init(ctx, req.Config, req.VerifyConnection) | 	newConf, err := p.SQLConnectionProducer.Init(ctx, req.Config, req.VerifyConnection) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.InitializeResponse{}, err | 		return dbplugin.InitializeResponse{}, err | ||||||
| 	} | 	} | ||||||
| 	resp := newdbplugin.InitializeResponse{ | 	resp := dbplugin.InitializeResponse{ | ||||||
| 		Config: newConf, | 		Config: newConf, | ||||||
| 	} | 	} | ||||||
| 	return resp, nil | 	return resp, nil | ||||||
| @@ -107,12 +107,12 @@ func (p *PostgreSQL) getConnection(ctx context.Context) (*sql.DB, error) { | |||||||
| 	return db.(*sql.DB), nil | 	return db.(*sql.DB), nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *PostgreSQL) UpdateUser(ctx context.Context, req newdbplugin.UpdateUserRequest) (newdbplugin.UpdateUserResponse, error) { | func (p *PostgreSQL) UpdateUser(ctx context.Context, req dbplugin.UpdateUserRequest) (dbplugin.UpdateUserResponse, error) { | ||||||
| 	if req.Username == "" { | 	if req.Username == "" { | ||||||
| 		return newdbplugin.UpdateUserResponse{}, fmt.Errorf("missing username") | 		return dbplugin.UpdateUserResponse{}, fmt.Errorf("missing username") | ||||||
| 	} | 	} | ||||||
| 	if req.Password == nil && req.Expiration == nil { | 	if req.Password == nil && req.Expiration == nil { | ||||||
| 		return newdbplugin.UpdateUserResponse{}, fmt.Errorf("no changes requested") | 		return dbplugin.UpdateUserResponse{}, fmt.Errorf("no changes requested") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	merr := &multierror.Error{} | 	merr := &multierror.Error{} | ||||||
| @@ -124,10 +124,10 @@ func (p *PostgreSQL) UpdateUser(ctx context.Context, req newdbplugin.UpdateUserR | |||||||
| 		err := p.changeUserExpiration(ctx, req.Username, req.Expiration) | 		err := p.changeUserExpiration(ctx, req.Username, req.Expiration) | ||||||
| 		merr = multierror.Append(merr, err) | 		merr = multierror.Append(merr, err) | ||||||
| 	} | 	} | ||||||
| 	return newdbplugin.UpdateUserResponse{}, merr.ErrorOrNil() | 	return dbplugin.UpdateUserResponse{}, merr.ErrorOrNil() | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *PostgreSQL) changeUserPassword(ctx context.Context, username string, changePass *newdbplugin.ChangePassword) error { | func (p *PostgreSQL) changeUserPassword(ctx context.Context, username string, changePass *dbplugin.ChangePassword) error { | ||||||
| 	stmts := changePass.Statements.Commands | 	stmts := changePass.Statements.Commands | ||||||
| 	if len(stmts) == 0 { | 	if len(stmts) == 0 { | ||||||
| 		stmts = []string{defaultChangePasswordStatement} | 		stmts = []string{defaultChangePasswordStatement} | ||||||
| @@ -184,7 +184,7 @@ func (p *PostgreSQL) changeUserPassword(ctx context.Context, username string, ch | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *PostgreSQL) changeUserExpiration(ctx context.Context, username string, changeExp *newdbplugin.ChangeExpiration) error { | func (p *PostgreSQL) changeUserExpiration(ctx context.Context, username string, changeExp *dbplugin.ChangeExpiration) error { | ||||||
| 	p.Lock() | 	p.Lock() | ||||||
| 	defer p.Unlock() | 	defer p.Unlock() | ||||||
|  |  | ||||||
| @@ -229,9 +229,9 @@ func (p *PostgreSQL) changeUserExpiration(ctx context.Context, username string, | |||||||
| 	return tx.Commit() | 	return tx.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *PostgreSQL) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) (newdbplugin.NewUserResponse, error) { | func (p *PostgreSQL) NewUser(ctx context.Context, req dbplugin.NewUserRequest) (dbplugin.NewUserResponse, error) { | ||||||
| 	if len(req.Statements.Commands) == 0 { | 	if len(req.Statements.Commands) == 0 { | ||||||
| 		return newdbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement | 		return dbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	p.Lock() | 	p.Lock() | ||||||
| @@ -244,19 +244,19 @@ func (p *PostgreSQL) NewUser(ctx context.Context, req newdbplugin.NewUserRequest | |||||||
| 		credsutil.MaxLength(63), | 		credsutil.MaxLength(63), | ||||||
| 	) | 	) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, err | 		return dbplugin.NewUserResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expirationStr := req.Expiration.Format(expirationFormat) | 	expirationStr := req.Expiration.Format(expirationFormat) | ||||||
|  |  | ||||||
| 	db, err := p.getConnection(ctx) | 	db, err := p.getConnection(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, fmt.Errorf("unable to get connection: %w", err) | 		return dbplugin.NewUserResponse{}, fmt.Errorf("unable to get connection: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tx, err := db.BeginTx(ctx, nil) | 	tx, err := db.BeginTx(ctx, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, fmt.Errorf("unable to start transaction: %w", err) | 		return dbplugin.NewUserResponse{}, fmt.Errorf("unable to start transaction: %w", err) | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
| 	defer tx.Rollback() | 	defer tx.Rollback() | ||||||
| @@ -271,7 +271,7 @@ func (p *PostgreSQL) NewUser(ctx context.Context, req newdbplugin.NewUserRequest | |||||||
| 				"expiration": expirationStr, | 				"expiration": expirationStr, | ||||||
| 			} | 			} | ||||||
| 			if err := dbtxn.ExecuteTxQuery(ctx, tx, m, stmt); err != nil { | 			if err := dbtxn.ExecuteTxQuery(ctx, tx, m, stmt); err != nil { | ||||||
| 				return newdbplugin.NewUserResponse{}, fmt.Errorf("failed to execute query: %w", err) | 				return dbplugin.NewUserResponse{}, fmt.Errorf("failed to execute query: %w", err) | ||||||
| 			} | 			} | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| @@ -289,30 +289,30 @@ func (p *PostgreSQL) NewUser(ctx context.Context, req newdbplugin.NewUserRequest | |||||||
| 				"expiration": expirationStr, | 				"expiration": expirationStr, | ||||||
| 			} | 			} | ||||||
| 			if err := dbtxn.ExecuteTxQuery(ctx, tx, m, query); err != nil { | 			if err := dbtxn.ExecuteTxQuery(ctx, tx, m, query); err != nil { | ||||||
| 				return newdbplugin.NewUserResponse{}, fmt.Errorf("failed to execute query: %w", err) | 				return dbplugin.NewUserResponse{}, fmt.Errorf("failed to execute query: %w", err) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := tx.Commit(); err != nil { | 	if err := tx.Commit(); err != nil { | ||||||
| 		return newdbplugin.NewUserResponse{}, err | 		return dbplugin.NewUserResponse{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	resp := newdbplugin.NewUserResponse{ | 	resp := dbplugin.NewUserResponse{ | ||||||
| 		Username: username, | 		Username: username, | ||||||
| 	} | 	} | ||||||
| 	return resp, nil | 	return resp, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *PostgreSQL) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserRequest) (newdbplugin.DeleteUserResponse, error) { | func (p *PostgreSQL) DeleteUser(ctx context.Context, req dbplugin.DeleteUserRequest) (dbplugin.DeleteUserResponse, error) { | ||||||
| 	p.Lock() | 	p.Lock() | ||||||
| 	defer p.Unlock() | 	defer p.Unlock() | ||||||
|  |  | ||||||
| 	if len(req.Statements.Commands) == 0 { | 	if len(req.Statements.Commands) == 0 { | ||||||
| 		return newdbplugin.DeleteUserResponse{}, p.defaultDeleteUser(ctx, req.Username) | 		return dbplugin.DeleteUserResponse{}, p.defaultDeleteUser(ctx, req.Username) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return newdbplugin.DeleteUserResponse{}, p.customDeleteUser(ctx, req.Username, req.Statements.Commands) | 	return dbplugin.DeleteUserResponse{}, p.customDeleteUser(ctx, req.Username, req.Statements.Commands) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *PostgreSQL) customDeleteUser(ctx context.Context, username string, revocationStmts []string) error { | func (p *PostgreSQL) customDeleteUser(ctx context.Context, username string, revocationStmts []string) error { | ||||||
|   | |||||||
| @@ -9,8 +9,8 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/helper/testhelpers/postgresql" | 	"github.com/hashicorp/vault/helper/testhelpers/postgresql" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	dbtesting "github.com/hashicorp/vault/sdk/database/newdbplugin/testing" | 	dbtesting "github.com/hashicorp/vault/sdk/database/dbplugin/v5/testing" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func getPostgreSQL(t *testing.T, options map[string]interface{}) (*PostgreSQL, func()) { | func getPostgreSQL(t *testing.T, options map[string]interface{}) (*PostgreSQL, func()) { | ||||||
| @@ -23,7 +23,7 @@ func getPostgreSQL(t *testing.T, options map[string]interface{}) (*PostgreSQL, f | |||||||
| 		connectionDetails[k] = v | 		connectionDetails[k] = v | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	req := newdbplugin.InitializeRequest{ | 	req := dbplugin.InitializeRequest{ | ||||||
| 		Config:           connectionDetails, | 		Config:           connectionDetails, | ||||||
| 		VerifyConnection: true, | 		VerifyConnection: true, | ||||||
| 	} | 	} | ||||||
| @@ -61,15 +61,15 @@ func TestPostgreSQL_InitializeWithStringVals(t *testing.T) { | |||||||
|  |  | ||||||
| func TestPostgreSQL_NewUser(t *testing.T) { | func TestPostgreSQL_NewUser(t *testing.T) { | ||||||
| 	type testCase struct { | 	type testCase struct { | ||||||
| 		req            newdbplugin.NewUserRequest | 		req            dbplugin.NewUserRequest | ||||||
| 		expectErr      bool | 		expectErr      bool | ||||||
| 		credsAssertion credsAssertion | 		credsAssertion credsAssertion | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tests := map[string]testCase{ | 	tests := map[string]testCase{ | ||||||
| 		"no creation statements": { | 		"no creation statements": { | ||||||
| 			req: newdbplugin.NewUserRequest{ | 			req: dbplugin.NewUserRequest{ | ||||||
| 				UsernameConfig: newdbplugin.UsernameMetadata{ | 				UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 					DisplayName: "test", | 					DisplayName: "test", | ||||||
| 					RoleName:    "test", | 					RoleName:    "test", | ||||||
| 				}, | 				}, | ||||||
| @@ -81,12 +81,12 @@ func TestPostgreSQL_NewUser(t *testing.T) { | |||||||
| 			credsAssertion: assertCredsDoNotExist, | 			credsAssertion: assertCredsDoNotExist, | ||||||
| 		}, | 		}, | ||||||
| 		"admin name": { | 		"admin name": { | ||||||
| 			req: newdbplugin.NewUserRequest{ | 			req: dbplugin.NewUserRequest{ | ||||||
| 				UsernameConfig: newdbplugin.UsernameMetadata{ | 				UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 					DisplayName: "test", | 					DisplayName: "test", | ||||||
| 					RoleName:    "test", | 					RoleName:    "test", | ||||||
| 				}, | 				}, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: dbplugin.Statements{ | ||||||
| 					Commands: []string{` | 					Commands: []string{` | ||||||
| 						CREATE ROLE "{{name}}" WITH | 						CREATE ROLE "{{name}}" WITH | ||||||
| 						  LOGIN | 						  LOGIN | ||||||
| @@ -102,12 +102,12 @@ func TestPostgreSQL_NewUser(t *testing.T) { | |||||||
| 			credsAssertion: assertCredsExist, | 			credsAssertion: assertCredsExist, | ||||||
| 		}, | 		}, | ||||||
| 		"admin username": { | 		"admin username": { | ||||||
| 			req: newdbplugin.NewUserRequest{ | 			req: dbplugin.NewUserRequest{ | ||||||
| 				UsernameConfig: newdbplugin.UsernameMetadata{ | 				UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 					DisplayName: "test", | 					DisplayName: "test", | ||||||
| 					RoleName:    "test", | 					RoleName:    "test", | ||||||
| 				}, | 				}, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: dbplugin.Statements{ | ||||||
| 					Commands: []string{` | 					Commands: []string{` | ||||||
| 						CREATE ROLE "{{username}}" WITH | 						CREATE ROLE "{{username}}" WITH | ||||||
| 						  LOGIN | 						  LOGIN | ||||||
| @@ -123,12 +123,12 @@ func TestPostgreSQL_NewUser(t *testing.T) { | |||||||
| 			credsAssertion: assertCredsExist, | 			credsAssertion: assertCredsExist, | ||||||
| 		}, | 		}, | ||||||
| 		"read only name": { | 		"read only name": { | ||||||
| 			req: newdbplugin.NewUserRequest{ | 			req: dbplugin.NewUserRequest{ | ||||||
| 				UsernameConfig: newdbplugin.UsernameMetadata{ | 				UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 					DisplayName: "test", | 					DisplayName: "test", | ||||||
| 					RoleName:    "test", | 					RoleName:    "test", | ||||||
| 				}, | 				}, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: dbplugin.Statements{ | ||||||
| 					Commands: []string{` | 					Commands: []string{` | ||||||
| 						CREATE ROLE "{{name}}" WITH | 						CREATE ROLE "{{name}}" WITH | ||||||
| 						  LOGIN | 						  LOGIN | ||||||
| @@ -145,12 +145,12 @@ func TestPostgreSQL_NewUser(t *testing.T) { | |||||||
| 			credsAssertion: assertCredsExist, | 			credsAssertion: assertCredsExist, | ||||||
| 		}, | 		}, | ||||||
| 		"read only username": { | 		"read only username": { | ||||||
| 			req: newdbplugin.NewUserRequest{ | 			req: dbplugin.NewUserRequest{ | ||||||
| 				UsernameConfig: newdbplugin.UsernameMetadata{ | 				UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 					DisplayName: "test", | 					DisplayName: "test", | ||||||
| 					RoleName:    "test", | 					RoleName:    "test", | ||||||
| 				}, | 				}, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: dbplugin.Statements{ | ||||||
| 					Commands: []string{` | 					Commands: []string{` | ||||||
| 						CREATE ROLE "{{username}}" WITH | 						CREATE ROLE "{{username}}" WITH | ||||||
| 						  LOGIN | 						  LOGIN | ||||||
| @@ -168,12 +168,12 @@ func TestPostgreSQL_NewUser(t *testing.T) { | |||||||
| 		}, | 		}, | ||||||
| 		// https://github.com/hashicorp/vault/issues/6098 | 		// https://github.com/hashicorp/vault/issues/6098 | ||||||
| 		"reproduce GH-6098": { | 		"reproduce GH-6098": { | ||||||
| 			req: newdbplugin.NewUserRequest{ | 			req: dbplugin.NewUserRequest{ | ||||||
| 				UsernameConfig: newdbplugin.UsernameMetadata{ | 				UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 					DisplayName: "test", | 					DisplayName: "test", | ||||||
| 					RoleName:    "test", | 					RoleName:    "test", | ||||||
| 				}, | 				}, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: dbplugin.Statements{ | ||||||
| 					Commands: []string{ | 					Commands: []string{ | ||||||
| 						// NOTE: "rolname" in the following line is not a typo. | 						// NOTE: "rolname" in the following line is not a typo. | ||||||
| 						"DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname='my_role') THEN CREATE ROLE my_role; END IF; END $$", | 						"DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname='my_role') THEN CREATE ROLE my_role; END IF; END $$", | ||||||
| @@ -186,12 +186,12 @@ func TestPostgreSQL_NewUser(t *testing.T) { | |||||||
| 			credsAssertion: assertCredsDoNotExist, | 			credsAssertion: assertCredsDoNotExist, | ||||||
| 		}, | 		}, | ||||||
| 		"reproduce issue with template": { | 		"reproduce issue with template": { | ||||||
| 			req: newdbplugin.NewUserRequest{ | 			req: dbplugin.NewUserRequest{ | ||||||
| 				UsernameConfig: newdbplugin.UsernameMetadata{ | 				UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 					DisplayName: "test", | 					DisplayName: "test", | ||||||
| 					RoleName:    "test", | 					RoleName:    "test", | ||||||
| 				}, | 				}, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: dbplugin.Statements{ | ||||||
| 					Commands: []string{ | 					Commands: []string{ | ||||||
| 						`DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname='my_role') THEN CREATE ROLE "{{username}}"; END IF; END $$`, | 						`DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname='my_role') THEN CREATE ROLE "{{username}}"; END IF; END $$`, | ||||||
| 					}, | 					}, | ||||||
| @@ -203,12 +203,12 @@ func TestPostgreSQL_NewUser(t *testing.T) { | |||||||
| 			credsAssertion: assertCredsDoNotExist, | 			credsAssertion: assertCredsDoNotExist, | ||||||
| 		}, | 		}, | ||||||
| 		"large block statements": { | 		"large block statements": { | ||||||
| 			req: newdbplugin.NewUserRequest{ | 			req: dbplugin.NewUserRequest{ | ||||||
| 				UsernameConfig: newdbplugin.UsernameMetadata{ | 				UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 					DisplayName: "test", | 					DisplayName: "test", | ||||||
| 					RoleName:    "test", | 					RoleName:    "test", | ||||||
| 				}, | 				}, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: dbplugin.Statements{ | ||||||
| 					Commands: newUserLargeBlockStatements, | 					Commands: newUserLargeBlockStatements, | ||||||
| 				}, | 				}, | ||||||
| 				Password:   "somesecurepassword", | 				Password:   "somesecurepassword", | ||||||
| @@ -284,12 +284,12 @@ func TestUpdateUser_Password(t *testing.T) { | |||||||
| 	for name, test := range tests { | 	for name, test := range tests { | ||||||
| 		t.Run(name, func(t *testing.T) { | 		t.Run(name, func(t *testing.T) { | ||||||
| 			initialPass := "myreallysecurepassword" | 			initialPass := "myreallysecurepassword" | ||||||
| 			createReq := newdbplugin.NewUserRequest{ | 			createReq := dbplugin.NewUserRequest{ | ||||||
| 				UsernameConfig: newdbplugin.UsernameMetadata{ | 				UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 					DisplayName: "test", | 					DisplayName: "test", | ||||||
| 					RoleName:    "test", | 					RoleName:    "test", | ||||||
| 				}, | 				}, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: dbplugin.Statements{ | ||||||
| 					Commands: []string{createAdminUser}, | 					Commands: []string{createAdminUser}, | ||||||
| 				}, | 				}, | ||||||
| 				Password:   initialPass, | 				Password:   initialPass, | ||||||
| @@ -300,11 +300,11 @@ func TestUpdateUser_Password(t *testing.T) { | |||||||
| 			assertCredsExist(t, db.ConnectionURL, createResp.Username, initialPass) | 			assertCredsExist(t, db.ConnectionURL, createResp.Username, initialPass) | ||||||
|  |  | ||||||
| 			newPass := "somenewpassword" | 			newPass := "somenewpassword" | ||||||
| 			updateReq := newdbplugin.UpdateUserRequest{ | 			updateReq := dbplugin.UpdateUserRequest{ | ||||||
| 				Username: createResp.Username, | 				Username: createResp.Username, | ||||||
| 				Password: &newdbplugin.ChangePassword{ | 				Password: &dbplugin.ChangePassword{ | ||||||
| 					NewPassword: newPass, | 					NewPassword: newPass, | ||||||
| 					Statements: newdbplugin.Statements{ | 					Statements: dbplugin.Statements{ | ||||||
| 						Commands: test.statements, | 						Commands: test.statements, | ||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
| @@ -326,11 +326,11 @@ func TestUpdateUser_Password(t *testing.T) { | |||||||
|  |  | ||||||
| 	t.Run("user does not exist", func(t *testing.T) { | 	t.Run("user does not exist", func(t *testing.T) { | ||||||
| 		newPass := "somenewpassword" | 		newPass := "somenewpassword" | ||||||
| 		updateReq := newdbplugin.UpdateUserRequest{ | 		updateReq := dbplugin.UpdateUserRequest{ | ||||||
| 			Username: "missing-user", | 			Username: "missing-user", | ||||||
| 			Password: &newdbplugin.ChangePassword{ | 			Password: &dbplugin.ChangePassword{ | ||||||
| 				NewPassword: newPass, | 				NewPassword: newPass, | ||||||
| 				Statements:  newdbplugin.Statements{}, | 				Statements:  dbplugin.Statements{}, | ||||||
| 			}, | 			}, | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -394,12 +394,12 @@ func TestUpdateUser_Expiration(t *testing.T) { | |||||||
| 		t.Run(name, func(t *testing.T) { | 		t.Run(name, func(t *testing.T) { | ||||||
| 			password := "myreallysecurepassword" | 			password := "myreallysecurepassword" | ||||||
| 			initialExpiration := test.initialExpiration.Truncate(time.Second) | 			initialExpiration := test.initialExpiration.Truncate(time.Second) | ||||||
| 			createReq := newdbplugin.NewUserRequest{ | 			createReq := dbplugin.NewUserRequest{ | ||||||
| 				UsernameConfig: newdbplugin.UsernameMetadata{ | 				UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 					DisplayName: "test", | 					DisplayName: "test", | ||||||
| 					RoleName:    "test", | 					RoleName:    "test", | ||||||
| 				}, | 				}, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: dbplugin.Statements{ | ||||||
| 					Commands: []string{createAdminUser}, | 					Commands: []string{createAdminUser}, | ||||||
| 				}, | 				}, | ||||||
| 				Password:   password, | 				Password:   password, | ||||||
| @@ -418,11 +418,11 @@ func TestUpdateUser_Expiration(t *testing.T) { | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			newExpiration := test.newExpiration.Truncate(time.Second) | 			newExpiration := test.newExpiration.Truncate(time.Second) | ||||||
| 			updateReq := newdbplugin.UpdateUserRequest{ | 			updateReq := dbplugin.UpdateUserRequest{ | ||||||
| 				Username: createResp.Username, | 				Username: createResp.Username, | ||||||
| 				Expiration: &newdbplugin.ChangeExpiration{ | 				Expiration: &dbplugin.ChangeExpiration{ | ||||||
| 					NewExpiration: newExpiration, | 					NewExpiration: newExpiration, | ||||||
| 					Statements: newdbplugin.Statements{ | 					Statements: dbplugin.Statements{ | ||||||
| 						Commands: test.statements, | 						Commands: test.statements, | ||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
| @@ -538,12 +538,12 @@ func TestDeleteUser(t *testing.T) { | |||||||
| 	for name, test := range tests { | 	for name, test := range tests { | ||||||
| 		t.Run(name, func(t *testing.T) { | 		t.Run(name, func(t *testing.T) { | ||||||
| 			password := "myreallysecurepassword" | 			password := "myreallysecurepassword" | ||||||
| 			createReq := newdbplugin.NewUserRequest{ | 			createReq := dbplugin.NewUserRequest{ | ||||||
| 				UsernameConfig: newdbplugin.UsernameMetadata{ | 				UsernameConfig: dbplugin.UsernameMetadata{ | ||||||
| 					DisplayName: "test", | 					DisplayName: "test", | ||||||
| 					RoleName:    "test", | 					RoleName:    "test", | ||||||
| 				}, | 				}, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: dbplugin.Statements{ | ||||||
| 					Commands: []string{createAdminUser}, | 					Commands: []string{createAdminUser}, | ||||||
| 				}, | 				}, | ||||||
| 				Password:   password, | 				Password:   password, | ||||||
| @@ -553,9 +553,9 @@ func TestDeleteUser(t *testing.T) { | |||||||
|  |  | ||||||
| 			assertCredsExist(t, db.ConnectionURL, createResp.Username, password) | 			assertCredsExist(t, db.ConnectionURL, createResp.Username, password) | ||||||
|  |  | ||||||
| 			deleteReq := newdbplugin.DeleteUserRequest{ | 			deleteReq := dbplugin.DeleteUserRequest{ | ||||||
| 				Username: createResp.Username, | 				Username: createResp.Username, | ||||||
| 				Statements: newdbplugin.Statements{ | 				Statements: dbplugin.Statements{ | ||||||
| 					Commands: test.revokeStmts, | 					Commands: test.revokeStmts, | ||||||
| 				}, | 				}, | ||||||
| 			} | 			} | ||||||
|   | |||||||
							
								
								
									
										506
									
								
								sdk/database/dbplugin/v5/conversions_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										506
									
								
								sdk/database/dbplugin/v5/conversions_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,506 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"reflect" | ||||||
|  | 	"strings" | ||||||
|  | 	"testing" | ||||||
|  | 	"time" | ||||||
|  | 	"unicode" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
|  |  | ||||||
|  | 	"google.golang.org/protobuf/types/known/structpb" | ||||||
|  | 	"google.golang.org/protobuf/types/known/timestamppb" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestConversionsHaveAllFields(t *testing.T) { | ||||||
|  | 	t.Run("initReqToProto", func(t *testing.T) { | ||||||
|  | 		req := InitializeRequest{ | ||||||
|  | 			Config: map[string]interface{}{ | ||||||
|  | 				"foo": map[string]interface{}{ | ||||||
|  | 					"bar": "baz", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			VerifyConnection: true, | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		protoReq, err := initReqToProto(req) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Failed to convert request to proto request: %s", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		values := getAllGetterValues(protoReq) | ||||||
|  | 		if len(values) == 0 { | ||||||
|  | 			// Probably a test failure - the protos used in these tests should have Get functions on them | ||||||
|  | 			t.Fatalf("No values found from Get functions!") | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		for _, gtr := range values { | ||||||
|  | 			err := assertAllFieldsSet(fmt.Sprintf("InitializeRequest.%s", gtr.name), gtr.value) | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Fatalf("%s", err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("newUserReqToProto", func(t *testing.T) { | ||||||
|  | 		req := NewUserRequest{ | ||||||
|  | 			UsernameConfig: UsernameMetadata{ | ||||||
|  | 				DisplayName: "dispName", | ||||||
|  | 				RoleName:    "roleName", | ||||||
|  | 			}, | ||||||
|  | 			Statements: Statements{ | ||||||
|  | 				Commands: []string{ | ||||||
|  | 					"statement", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			RollbackStatements: Statements{ | ||||||
|  | 				Commands: []string{ | ||||||
|  | 					"rollback_statement", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			Password:   "password", | ||||||
|  | 			Expiration: time.Now(), | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		protoReq, err := newUserReqToProto(req) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Failed to convert request to proto request: %s", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		values := getAllGetterValues(protoReq) | ||||||
|  | 		if len(values) == 0 { | ||||||
|  | 			// Probably a test failure - the protos used in these tests should have Get functions on them | ||||||
|  | 			t.Fatalf("No values found from Get functions!") | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		for _, gtr := range values { | ||||||
|  | 			err := assertAllFieldsSet(fmt.Sprintf("NewUserRequest.%s", gtr.name), gtr.value) | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Fatalf("%s", err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("updateUserReqToProto", func(t *testing.T) { | ||||||
|  | 		req := UpdateUserRequest{ | ||||||
|  | 			Username: "username", | ||||||
|  | 			Password: &ChangePassword{ | ||||||
|  | 				NewPassword: "newpassword", | ||||||
|  | 				Statements: Statements{ | ||||||
|  | 					Commands: []string{ | ||||||
|  | 						"statement", | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			Expiration: &ChangeExpiration{ | ||||||
|  | 				NewExpiration: time.Now(), | ||||||
|  | 				Statements: Statements{ | ||||||
|  | 					Commands: []string{ | ||||||
|  | 						"statement", | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		protoReq, err := updateUserReqToProto(req) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Failed to convert request to proto request: %s", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		values := getAllGetterValues(protoReq) | ||||||
|  | 		if len(values) == 0 { | ||||||
|  | 			// Probably a test failure - the protos used in these tests should have Get functions on them | ||||||
|  | 			t.Fatalf("No values found from Get functions!") | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		for _, gtr := range values { | ||||||
|  | 			err := assertAllFieldsSet(fmt.Sprintf("UpdateUserRequest.%s", gtr.name), gtr.value) | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Fatalf("%s", err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("deleteUserReqToProto", func(t *testing.T) { | ||||||
|  | 		req := DeleteUserRequest{ | ||||||
|  | 			Username: "username", | ||||||
|  | 			Statements: Statements{ | ||||||
|  | 				Commands: []string{ | ||||||
|  | 					"statement", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		protoReq, err := deleteUserReqToProto(req) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Failed to convert request to proto request: %s", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		values := getAllGetterValues(protoReq) | ||||||
|  | 		if len(values) == 0 { | ||||||
|  | 			// Probably a test failure - the protos used in these tests should have Get functions on them | ||||||
|  | 			t.Fatalf("No values found from Get functions!") | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		for _, gtr := range values { | ||||||
|  | 			err := assertAllFieldsSet(fmt.Sprintf("DeleteUserRequest.%s", gtr.name), gtr.value) | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Fatalf("%s", err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("getUpdateUserRequest", func(t *testing.T) { | ||||||
|  | 		req := &proto.UpdateUserRequest{ | ||||||
|  | 			Username: "username", | ||||||
|  | 			Password: &proto.ChangePassword{ | ||||||
|  | 				NewPassword: "newpass", | ||||||
|  | 				Statements: &proto.Statements{ | ||||||
|  | 					Commands: []string{ | ||||||
|  | 						"statement", | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			Expiration: &proto.ChangeExpiration{ | ||||||
|  | 				NewExpiration: timestamppb.Now(), | ||||||
|  | 				Statements: &proto.Statements{ | ||||||
|  | 					Commands: []string{ | ||||||
|  | 						"statement", | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		protoReq, err := getUpdateUserRequest(req) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Failed to convert request to proto request: %s", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		err = assertAllFieldsSet("proto.UpdateUserRequest", protoReq) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("%s", err) | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type getter struct { | ||||||
|  | 	name  string | ||||||
|  | 	value interface{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func getAllGetterValues(value interface{}) (values []getter) { | ||||||
|  | 	typ := reflect.TypeOf(value) | ||||||
|  | 	val := reflect.ValueOf(value) | ||||||
|  | 	for i := 0; i < typ.NumMethod(); i++ { | ||||||
|  | 		method := typ.Method(i) | ||||||
|  | 		if !strings.HasPrefix(method.Name, "Get") { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		valMethod := val.Method(i) | ||||||
|  | 		resp := valMethod.Call(nil) | ||||||
|  | 		getVal := resp[0].Interface() | ||||||
|  | 		gtr := getter{ | ||||||
|  | 			name:  strings.TrimPrefix(method.Name, "Get"), | ||||||
|  | 			value: getVal, | ||||||
|  | 		} | ||||||
|  | 		values = append(values, gtr) | ||||||
|  | 	} | ||||||
|  | 	return values | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Ensures the assertion works properly | ||||||
|  | func TestAssertAllFieldsSet(t *testing.T) { | ||||||
|  | 	type testCase struct { | ||||||
|  | 		value     interface{} | ||||||
|  | 		expectErr bool | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tests := map[string]testCase{ | ||||||
|  | 		"zero int": { | ||||||
|  | 			value:     0, | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"non-zero int": { | ||||||
|  | 			value:     1, | ||||||
|  | 			expectErr: false, | ||||||
|  | 		}, | ||||||
|  | 		"zero float64": { | ||||||
|  | 			value:     0.0, | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"non-zero float64": { | ||||||
|  | 			value:     1.0, | ||||||
|  | 			expectErr: false, | ||||||
|  | 		}, | ||||||
|  | 		"empty string": { | ||||||
|  | 			value:     "", | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"true boolean": { | ||||||
|  | 			value:     true, | ||||||
|  | 			expectErr: false, | ||||||
|  | 		}, | ||||||
|  | 		"false boolean": { // False is an exception to the "is zero" rule | ||||||
|  | 			value:     false, | ||||||
|  | 			expectErr: false, | ||||||
|  | 		}, | ||||||
|  | 		"blank struct": { | ||||||
|  | 			value:     struct{}{}, | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"non-blank but empty struct": { | ||||||
|  | 			value: struct { | ||||||
|  | 				str string | ||||||
|  | 			}{ | ||||||
|  | 				str: "", | ||||||
|  | 			}, | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"non-empty string": { | ||||||
|  | 			value:     "foo", | ||||||
|  | 			expectErr: false, | ||||||
|  | 		}, | ||||||
|  | 		"non-empty struct": { | ||||||
|  | 			value: struct { | ||||||
|  | 				str string | ||||||
|  | 			}{ | ||||||
|  | 				str: "foo", | ||||||
|  | 			}, | ||||||
|  | 			expectErr: false, | ||||||
|  | 		}, | ||||||
|  | 		"empty nested struct": { | ||||||
|  | 			value: struct { | ||||||
|  | 				Str       string | ||||||
|  | 				Substruct struct { | ||||||
|  | 					Substr string | ||||||
|  | 				} | ||||||
|  | 			}{ | ||||||
|  | 				Str: "foo", | ||||||
|  | 				Substruct: struct { | ||||||
|  | 					Substr string | ||||||
|  | 				}{}, // Empty sub-field | ||||||
|  | 			}, | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"filled nested struct": { | ||||||
|  | 			value: struct { | ||||||
|  | 				str       string | ||||||
|  | 				substruct struct { | ||||||
|  | 					substr string | ||||||
|  | 				} | ||||||
|  | 			}{ | ||||||
|  | 				str: "foo", | ||||||
|  | 				substruct: struct { | ||||||
|  | 					substr string | ||||||
|  | 				}{ | ||||||
|  | 					substr: "sub-foo", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			expectErr: false, | ||||||
|  | 		}, | ||||||
|  | 		"nil map": { | ||||||
|  | 			value:     map[string]string(nil), | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"empty map": { | ||||||
|  | 			value:     map[string]string{}, | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"filled map": { | ||||||
|  | 			value: map[string]string{ | ||||||
|  | 				"foo": "bar", | ||||||
|  | 				"int": "42", | ||||||
|  | 			}, | ||||||
|  | 			expectErr: false, | ||||||
|  | 		}, | ||||||
|  | 		"map with empty string value": { | ||||||
|  | 			value: map[string]string{ | ||||||
|  | 				"foo": "", | ||||||
|  | 			}, | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"nested map with empty string value": { | ||||||
|  | 			value: map[string]interface{}{ | ||||||
|  | 				"bar": "baz", | ||||||
|  | 				"foo": map[string]interface{}{ | ||||||
|  | 					"subfoo": "", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"nil slice": { | ||||||
|  | 			value:     []string(nil), | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"empty slice": { | ||||||
|  | 			value:     []string{}, | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"filled slice": { | ||||||
|  | 			value: []string{ | ||||||
|  | 				"foo", | ||||||
|  | 			}, | ||||||
|  | 			expectErr: false, | ||||||
|  | 		}, | ||||||
|  | 		"slice with empty string value": { | ||||||
|  | 			value: []string{ | ||||||
|  | 				"", | ||||||
|  | 			}, | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"empty structpb": { | ||||||
|  | 			value:     newStructPb(t, map[string]interface{}{}), | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"filled structpb": { | ||||||
|  | 			value: newStructPb(t, map[string]interface{}{ | ||||||
|  | 				"foo": "bar", | ||||||
|  | 				"int": 42, | ||||||
|  | 			}), | ||||||
|  | 			expectErr: false, | ||||||
|  | 		}, | ||||||
|  |  | ||||||
|  | 		"pointer to zero int": { | ||||||
|  | 			value:     intPtr(0), | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"pointer to non-zero int": { | ||||||
|  | 			value:     intPtr(1), | ||||||
|  | 			expectErr: false, | ||||||
|  | 		}, | ||||||
|  | 		"pointer to zero float64": { | ||||||
|  | 			value:     float64Ptr(0.0), | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"pointer to non-zero float64": { | ||||||
|  | 			value:     float64Ptr(1.0), | ||||||
|  | 			expectErr: false, | ||||||
|  | 		}, | ||||||
|  | 		"pointer to nil string": { | ||||||
|  | 			value:     new(string), | ||||||
|  | 			expectErr: true, | ||||||
|  | 		}, | ||||||
|  | 		"pointer to non-nil string": { | ||||||
|  | 			value:     strPtr("foo"), | ||||||
|  | 			expectErr: false, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for name, test := range tests { | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			err := assertAllFieldsSet("", test.value) | ||||||
|  | 			if test.expectErr && err == nil { | ||||||
|  | 				t.Fatalf("err expected, got nil") | ||||||
|  | 			} | ||||||
|  | 			if !test.expectErr && err != nil { | ||||||
|  | 				t.Fatalf("no error expected, got: %s", err) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func assertAllFieldsSet(name string, val interface{}) error { | ||||||
|  | 	if val == nil { | ||||||
|  | 		return fmt.Errorf("value is nil") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rVal := reflect.ValueOf(val) | ||||||
|  | 	return assertAllFieldsSetValue(name, rVal) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func assertAllFieldsSetValue(name string, rVal reflect.Value) error { | ||||||
|  | 	// All booleans are allowed - we don't have a way of differentiating between | ||||||
|  | 	// and intentional false and a missing false | ||||||
|  | 	if rVal.Kind() == reflect.Bool { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Primitives fall through here | ||||||
|  | 	if rVal.IsZero() { | ||||||
|  | 		return fmt.Errorf("%s is zero", name) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	switch rVal.Kind() { | ||||||
|  | 	case reflect.Ptr, reflect.Interface: | ||||||
|  | 		return assertAllFieldsSetValue(name, rVal.Elem()) | ||||||
|  | 	case reflect.Struct: | ||||||
|  | 		return assertAllFieldsSetStruct(name, rVal) | ||||||
|  | 	case reflect.Map: | ||||||
|  | 		if rVal.Len() == 0 { | ||||||
|  | 			return fmt.Errorf("%s (map type) is empty", name) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		iter := rVal.MapRange() | ||||||
|  | 		for iter.Next() { | ||||||
|  | 			k := iter.Key() | ||||||
|  | 			v := iter.Value() | ||||||
|  |  | ||||||
|  | 			err := assertAllFieldsSetValue(fmt.Sprintf("%s[%s]", name, k), v) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	case reflect.Slice: | ||||||
|  | 		if rVal.Len() == 0 { | ||||||
|  | 			return fmt.Errorf("%s (slice type) is empty", name) | ||||||
|  | 		} | ||||||
|  | 		for i := 0; i < rVal.Len(); i++ { | ||||||
|  | 			sliceVal := rVal.Index(i) | ||||||
|  | 			err := assertAllFieldsSetValue(fmt.Sprintf("%s[%d]", name, i), sliceVal) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func assertAllFieldsSetStruct(name string, rVal reflect.Value) error { | ||||||
|  | 	switch rVal.Type() { | ||||||
|  | 	case reflect.TypeOf(timestamppb.Timestamp{}): | ||||||
|  | 		ts := rVal.Interface().(timestamppb.Timestamp) | ||||||
|  | 		if ts.AsTime().IsZero() { | ||||||
|  | 			return fmt.Errorf("%s is zero", name) | ||||||
|  | 		} | ||||||
|  | 		return nil | ||||||
|  | 	default: | ||||||
|  | 		for i := 0; i < rVal.NumField(); i++ { | ||||||
|  | 			field := rVal.Field(i) | ||||||
|  | 			fieldName := rVal.Type().Field(i) | ||||||
|  |  | ||||||
|  | 			// Skip fields that aren't exported | ||||||
|  | 			if unicode.IsLower([]rune(fieldName.Name)[0]) { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			err := assertAllFieldsSetValue(fmt.Sprintf("%s.%s", name, fieldName.Name), field) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func intPtr(i int) *int { | ||||||
|  | 	return &i | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func float64Ptr(f float64) *float64 { | ||||||
|  | 	return &f | ||||||
|  | } | ||||||
|  | func strPtr(str string) *string { | ||||||
|  | 	return &str | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newStructPb(t *testing.T, m map[string]interface{}) *structpb.Struct { | ||||||
|  | 	t.Helper() | ||||||
|  |  | ||||||
|  | 	s, err := structpb.NewStruct(m) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Failed to convert map to struct: %s", err) | ||||||
|  | 	} | ||||||
|  | 	return s | ||||||
|  | } | ||||||
							
								
								
									
										178
									
								
								sdk/database/dbplugin/v5/database.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								sdk/database/dbplugin/v5/database.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,178 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Database to manipulate users within an external system (typically a database). | ||||||
|  | type Database interface { | ||||||
|  | 	// Initialize the database plugin. This is the equivalent of a constructor for the | ||||||
|  | 	// database object itself. | ||||||
|  | 	Initialize(ctx context.Context, req InitializeRequest) (InitializeResponse, error) | ||||||
|  |  | ||||||
|  | 	// NewUser creates a new user within the database. This user is temporary in that it | ||||||
|  | 	// will exist until the TTL expires. | ||||||
|  | 	NewUser(ctx context.Context, req NewUserRequest) (NewUserResponse, error) | ||||||
|  |  | ||||||
|  | 	// UpdateUser updates an existing user within the database. | ||||||
|  | 	UpdateUser(ctx context.Context, req UpdateUserRequest) (UpdateUserResponse, error) | ||||||
|  |  | ||||||
|  | 	// DeleteUser from the database. This should not error if the user didn't | ||||||
|  | 	// exist prior to this call. | ||||||
|  | 	DeleteUser(ctx context.Context, req DeleteUserRequest) (DeleteUserResponse, error) | ||||||
|  |  | ||||||
|  | 	// Type returns the Name 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. This is used | ||||||
|  | 	// for things like metrics and logging. No behavior is switched on this. | ||||||
|  | 	Type() (string, error) | ||||||
|  |  | ||||||
|  | 	// Close attempts to close the underlying database connection that was | ||||||
|  | 	// established by the backend. | ||||||
|  | 	Close() error | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // /////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Database Request & Response Objects | ||||||
|  | // These request and response objects are *not* protobuf types because gRPC does not | ||||||
|  | // support all types that we need in a nice way. For instance, gRPC does not support | ||||||
|  | // map[string]interface{}. It does have an `Any` type, but converting it to a map | ||||||
|  | // requires extensive use of reflection and knowing what types to support ahead of | ||||||
|  | // time. Instead these types are made as user-friendly as possible so the conversion | ||||||
|  | // between protobuf types and request/response objects is handled by Vault developers | ||||||
|  | // rather than needing to be handled by external plugin developers. | ||||||
|  | // /////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  | // Initialize() | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | // InitializeRequest contains all information needed to initialize a database plugin. | ||||||
|  | type InitializeRequest struct { | ||||||
|  | 	// Config to initialize the database with. This can include things like connection details, | ||||||
|  | 	// a "root" username & password, etc. This will not include all configuration items specified | ||||||
|  | 	// when configuring the database. Some values will be stripped out by the database engine | ||||||
|  | 	// prior to being passed to the plugin. | ||||||
|  | 	Config map[string]interface{} | ||||||
|  |  | ||||||
|  | 	// VerifyConnection during initialization. If true, a connection should be made to the | ||||||
|  | 	// database to verify the connection can be made. If false, no connection should be made | ||||||
|  | 	// on initialization. | ||||||
|  | 	VerifyConnection bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // InitializeResponse returns any information Vault needs to know after initializing | ||||||
|  | // a database plugin. | ||||||
|  | type InitializeResponse struct { | ||||||
|  | 	// Config that should be saved in Vault. This may differ from the config in the request, | ||||||
|  | 	// but should contain everything required to Initialize the database. | ||||||
|  | 	// REQUIRED in order to save the configuration into Vault after initialization | ||||||
|  | 	Config map[string]interface{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  | // NewUser() | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | // NewUserRequest request a new user is created | ||||||
|  | type NewUserRequest struct { | ||||||
|  | 	// UsernameConfig is metadata that can be used to generate a username | ||||||
|  | 	// within the database plugin | ||||||
|  | 	UsernameConfig UsernameMetadata | ||||||
|  |  | ||||||
|  | 	// Statements is an ordered list of commands to run within the database when | ||||||
|  | 	// creating a new user. This frequently includes permissions to give the | ||||||
|  | 	// user or similar actions. | ||||||
|  | 	Statements Statements | ||||||
|  |  | ||||||
|  | 	// RollbackStatements is an ordered list of commands to run within the database | ||||||
|  | 	// if the new user creation process fails. | ||||||
|  | 	RollbackStatements Statements | ||||||
|  |  | ||||||
|  | 	// Password credentials to use when creating the user | ||||||
|  | 	Password string | ||||||
|  |  | ||||||
|  | 	// Expiration of the user. Not all database plugins will support this. | ||||||
|  | 	Expiration time.Time | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // UsernameMetadata is metadata the database plugin can use to generate a username | ||||||
|  | type UsernameMetadata struct { | ||||||
|  | 	DisplayName string | ||||||
|  | 	RoleName    string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewUserResponse returns any information Vault needs to know after creating a new user. | ||||||
|  | type NewUserResponse struct { | ||||||
|  | 	// Username of the user created within the database. | ||||||
|  | 	// REQUIRED so Vault knows the name of the user that was created | ||||||
|  | 	Username string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  | // UpdateUser() | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | type UpdateUserRequest struct { | ||||||
|  | 	// Username to make changes to. | ||||||
|  | 	Username string | ||||||
|  |  | ||||||
|  | 	// Password indicates the new password to change to. | ||||||
|  | 	// If nil, no change is requested. | ||||||
|  | 	Password *ChangePassword | ||||||
|  |  | ||||||
|  | 	// Expiration indicates the new expiration date to change to. | ||||||
|  | 	// If nil, no change is requested. | ||||||
|  | 	Expiration *ChangeExpiration | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ChangePassword of a given user | ||||||
|  | type ChangePassword struct { | ||||||
|  | 	// NewPassword for the user | ||||||
|  | 	NewPassword string | ||||||
|  |  | ||||||
|  | 	// Statements is an ordered list of commands to run within the database | ||||||
|  | 	// when changing the user's password. | ||||||
|  | 	Statements Statements | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ChangeExpiration of a given user | ||||||
|  | type ChangeExpiration struct { | ||||||
|  | 	// NewExpiration of the user | ||||||
|  | 	NewExpiration time.Time | ||||||
|  |  | ||||||
|  | 	// Statements is an ordered list of commands to run within the database | ||||||
|  | 	// when changing the user's expiration. | ||||||
|  | 	Statements Statements | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type UpdateUserResponse struct{} | ||||||
|  |  | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  | // DeleteUser() | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | type DeleteUserRequest struct { | ||||||
|  | 	// Username to delete from the database | ||||||
|  | 	Username string | ||||||
|  |  | ||||||
|  | 	// Statements is an ordered list of commands to run within the database | ||||||
|  | 	// when deleting a user. | ||||||
|  | 	Statements Statements | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type DeleteUserResponse struct{} | ||||||
|  |  | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  | // Used across multiple functions | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | // Statements wraps a collection of statements to run in a database when an | ||||||
|  | // operation is performed (create, update, etc.). This is a struct rather than | ||||||
|  | // a string slice so we can easily add more information to this in the future. | ||||||
|  | type Statements struct { | ||||||
|  | 	// Commands is an ordered list of commands to execute in the database. | ||||||
|  | 	// These commands may include templated fields such as {{username}} and {{password}} | ||||||
|  | 	Commands []string | ||||||
|  | } | ||||||
							
								
								
									
										254
									
								
								sdk/database/dbplugin/v5/grpc_client.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								sdk/database/dbplugin/v5/grpc_client.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,254 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/golang/protobuf/ptypes" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/helper/pluginutil" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	_ Database = gRPCClient{} | ||||||
|  |  | ||||||
|  | 	ErrPluginShutdown = errors.New("plugin shutdown") | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type gRPCClient struct { | ||||||
|  | 	client  proto.DatabaseClient | ||||||
|  | 	doneCtx context.Context | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c gRPCClient) Initialize(ctx context.Context, req InitializeRequest) (InitializeResponse, error) { | ||||||
|  | 	rpcReq, err := initReqToProto(req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return InitializeResponse{}, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcResp, err := c.client.Initialize(ctx, rpcReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return InitializeResponse{}, fmt.Errorf("unable to initialize: %s", err.Error()) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return initRespFromProto(rpcResp) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func initReqToProto(req InitializeRequest) (*proto.InitializeRequest, error) { | ||||||
|  | 	config, err := mapToStruct(req.Config) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("unable to marshal config: %w", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcReq := &proto.InitializeRequest{ | ||||||
|  | 		ConfigData:       config, | ||||||
|  | 		VerifyConnection: req.VerifyConnection, | ||||||
|  | 	} | ||||||
|  | 	return rpcReq, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func initRespFromProto(rpcResp *proto.InitializeResponse) (InitializeResponse, error) { | ||||||
|  | 	newConfig := structToMap(rpcResp.GetConfigData()) | ||||||
|  |  | ||||||
|  | 	resp := InitializeResponse{ | ||||||
|  | 		Config: newConfig, | ||||||
|  | 	} | ||||||
|  | 	return resp, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c gRPCClient) NewUser(ctx context.Context, req NewUserRequest) (NewUserResponse, error) { | ||||||
|  | 	ctx, cancel := context.WithCancel(ctx) | ||||||
|  | 	quitCh := pluginutil.CtxCancelIfCanceled(cancel, c.doneCtx) | ||||||
|  | 	defer close(quitCh) | ||||||
|  | 	defer cancel() | ||||||
|  |  | ||||||
|  | 	rpcReq, err := newUserReqToProto(req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return NewUserResponse{}, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcResp, err := c.client.NewUser(ctx, rpcReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if c.doneCtx.Err() != nil { | ||||||
|  | 			return NewUserResponse{}, ErrPluginShutdown | ||||||
|  | 		} | ||||||
|  | 		return NewUserResponse{}, fmt.Errorf("unable to create new user: %w", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return newUserRespFromProto(rpcResp) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newUserReqToProto(req NewUserRequest) (*proto.NewUserRequest, error) { | ||||||
|  | 	if req.Password == "" { | ||||||
|  | 		return nil, fmt.Errorf("missing password") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	expiration, err := ptypes.TimestampProto(req.Expiration) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("unable to marshal expiration date: %w", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcReq := &proto.NewUserRequest{ | ||||||
|  | 		UsernameConfig: &proto.UsernameConfig{ | ||||||
|  | 			DisplayName: req.UsernameConfig.DisplayName, | ||||||
|  | 			RoleName:    req.UsernameConfig.RoleName, | ||||||
|  | 		}, | ||||||
|  | 		Password:   req.Password, | ||||||
|  | 		Expiration: expiration, | ||||||
|  | 		Statements: &proto.Statements{ | ||||||
|  | 			Commands: req.Statements.Commands, | ||||||
|  | 		}, | ||||||
|  | 		RollbackStatements: &proto.Statements{ | ||||||
|  | 			Commands: req.RollbackStatements.Commands, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	return rpcReq, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newUserRespFromProto(rpcResp *proto.NewUserResponse) (NewUserResponse, error) { | ||||||
|  | 	resp := NewUserResponse{ | ||||||
|  | 		Username: rpcResp.GetUsername(), | ||||||
|  | 	} | ||||||
|  | 	return resp, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c gRPCClient) UpdateUser(ctx context.Context, req UpdateUserRequest) (UpdateUserResponse, error) { | ||||||
|  | 	rpcReq, err := updateUserReqToProto(req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return UpdateUserResponse{}, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcResp, err := c.client.UpdateUser(ctx, rpcReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if c.doneCtx.Err() != nil { | ||||||
|  | 			return UpdateUserResponse{}, ErrPluginShutdown | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return UpdateUserResponse{}, fmt.Errorf("unable to update user: %w", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return updateUserRespFromProto(rpcResp) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func updateUserReqToProto(req UpdateUserRequest) (*proto.UpdateUserRequest, error) { | ||||||
|  | 	if req.Username == "" { | ||||||
|  | 		return nil, fmt.Errorf("missing username") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (req.Password == nil || req.Password.NewPassword == "") && | ||||||
|  | 		(req.Expiration == nil || req.Expiration.NewExpiration.IsZero()) { | ||||||
|  | 		return nil, fmt.Errorf("missing changes") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	expiration, err := expirationToProto(req.Expiration) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("unable to parse new expiration date: %w", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var password *proto.ChangePassword | ||||||
|  | 	if req.Password != nil && req.Password.NewPassword != "" { | ||||||
|  | 		password = &proto.ChangePassword{ | ||||||
|  | 			NewPassword: req.Password.NewPassword, | ||||||
|  | 			Statements: &proto.Statements{ | ||||||
|  | 				Commands: req.Password.Statements.Commands, | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcReq := &proto.UpdateUserRequest{ | ||||||
|  | 		Username:   req.Username, | ||||||
|  | 		Password:   password, | ||||||
|  | 		Expiration: expiration, | ||||||
|  | 	} | ||||||
|  | 	return rpcReq, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func updateUserRespFromProto(rpcResp *proto.UpdateUserResponse) (UpdateUserResponse, error) { | ||||||
|  | 	// Placeholder for future conversion if data is returned | ||||||
|  | 	return UpdateUserResponse{}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func expirationToProto(exp *ChangeExpiration) (*proto.ChangeExpiration, error) { | ||||||
|  | 	if exp == nil { | ||||||
|  | 		return nil, nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	expiration, err := ptypes.TimestampProto(exp.NewExpiration) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	changeExp := &proto.ChangeExpiration{ | ||||||
|  | 		NewExpiration: expiration, | ||||||
|  | 		Statements: &proto.Statements{ | ||||||
|  | 			Commands: exp.Statements.Commands, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	return changeExp, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c gRPCClient) DeleteUser(ctx context.Context, req DeleteUserRequest) (DeleteUserResponse, error) { | ||||||
|  | 	rpcReq, err := deleteUserReqToProto(req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return DeleteUserResponse{}, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcResp, err := c.client.DeleteUser(ctx, rpcReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if c.doneCtx.Err() != nil { | ||||||
|  | 			return DeleteUserResponse{}, ErrPluginShutdown | ||||||
|  | 		} | ||||||
|  | 		return DeleteUserResponse{}, fmt.Errorf("unable to update user: %w", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return deleteUserRespFromProto(rpcResp) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func deleteUserReqToProto(req DeleteUserRequest) (*proto.DeleteUserRequest, error) { | ||||||
|  | 	if req.Username == "" { | ||||||
|  | 		return nil, fmt.Errorf("missing username") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcReq := &proto.DeleteUserRequest{ | ||||||
|  | 		Username: req.Username, | ||||||
|  | 		Statements: &proto.Statements{ | ||||||
|  | 			Commands: req.Statements.Commands, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	return rpcReq, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func deleteUserRespFromProto(rpcResp *proto.DeleteUserResponse) (DeleteUserResponse, error) { | ||||||
|  | 	// Placeholder for future conversion if data is returned | ||||||
|  | 	return DeleteUserResponse{}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c gRPCClient) Type() (string, error) { | ||||||
|  | 	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) | ||||||
|  | 	defer cancel() | ||||||
|  |  | ||||||
|  | 	typeResp, err := c.client.Type(ctx, &proto.Empty{}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if c.doneCtx.Err() != nil { | ||||||
|  | 			return "", ErrPluginShutdown | ||||||
|  | 		} | ||||||
|  | 		return "", fmt.Errorf("unable to get database plugin type: %w", err) | ||||||
|  | 	} | ||||||
|  | 	return typeResp.GetType(), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c gRPCClient) Close() error { | ||||||
|  | 	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) | ||||||
|  | 	defer cancel() | ||||||
|  |  | ||||||
|  | 	_, err := c.client.Close(ctx, &proto.Empty{}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if c.doneCtx.Err() != nil { | ||||||
|  | 			return ErrPluginShutdown | ||||||
|  | 		} | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										537
									
								
								sdk/database/dbplugin/v5/grpc_client_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										537
									
								
								sdk/database/dbplugin/v5/grpc_client_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,537 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"errors" | ||||||
|  | 	"reflect" | ||||||
|  | 	"testing" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
|  | 	"google.golang.org/grpc" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestGRPCClient_Initialize(t *testing.T) { | ||||||
|  | 	type testCase struct { | ||||||
|  | 		client       proto.DatabaseClient | ||||||
|  | 		req          InitializeRequest | ||||||
|  | 		expectedResp InitializeResponse | ||||||
|  | 		assertErr    errorAssertion | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tests := map[string]testCase{ | ||||||
|  | 		"bad config": { | ||||||
|  | 			client: fakeClient{}, | ||||||
|  | 			req: InitializeRequest{ | ||||||
|  | 				Config: map[string]interface{}{ | ||||||
|  | 					"foo": badJSONValue{}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			assertErr: assertErrNotNil, | ||||||
|  | 		}, | ||||||
|  | 		"database error": { | ||||||
|  | 			client: fakeClient{ | ||||||
|  | 				initErr: errors.New("initialize error"), | ||||||
|  | 			}, | ||||||
|  | 			req: InitializeRequest{ | ||||||
|  | 				Config: map[string]interface{}{ | ||||||
|  | 					"foo": "bar", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			assertErr: assertErrNotNil, | ||||||
|  | 		}, | ||||||
|  | 		"happy path": { | ||||||
|  | 			client: fakeClient{ | ||||||
|  | 				initResp: &proto.InitializeResponse{ | ||||||
|  | 					ConfigData: marshal(t, map[string]interface{}{ | ||||||
|  | 						"foo": "bar", | ||||||
|  | 						"baz": "biz", | ||||||
|  | 					}), | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			req: InitializeRequest{ | ||||||
|  | 				Config: map[string]interface{}{ | ||||||
|  | 					"foo": "bar", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			expectedResp: InitializeResponse{ | ||||||
|  | 				Config: map[string]interface{}{ | ||||||
|  | 					"foo": "bar", | ||||||
|  | 					"baz": "biz", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			assertErr: assertErrNil, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for name, test := range tests { | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			c := gRPCClient{ | ||||||
|  | 				client:  test.client, | ||||||
|  | 				doneCtx: nil, | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// Context doesn't need to timeout since this is just passed through | ||||||
|  | 			ctx := context.Background() | ||||||
|  |  | ||||||
|  | 			resp, err := c.Initialize(ctx, test.req) | ||||||
|  | 			test.assertErr(t, err) | ||||||
|  |  | ||||||
|  | 			if !reflect.DeepEqual(resp, test.expectedResp) { | ||||||
|  | 				t.Fatalf("Actual response: %#v\nExpected response: %#v", resp, test.expectedResp) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestGRPCClient_NewUser(t *testing.T) { | ||||||
|  | 	runningCtx := context.Background() | ||||||
|  | 	cancelledCtx, cancel := context.WithCancel(context.Background()) | ||||||
|  | 	cancel() | ||||||
|  |  | ||||||
|  | 	type testCase struct { | ||||||
|  | 		client       proto.DatabaseClient | ||||||
|  | 		req          NewUserRequest | ||||||
|  | 		doneCtx      context.Context | ||||||
|  | 		expectedResp NewUserResponse | ||||||
|  | 		assertErr    errorAssertion | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tests := map[string]testCase{ | ||||||
|  | 		"missing password": { | ||||||
|  | 			client: fakeClient{}, | ||||||
|  | 			req: NewUserRequest{ | ||||||
|  | 				Password:   "", | ||||||
|  | 				Expiration: time.Now(), | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNotNil, | ||||||
|  | 		}, | ||||||
|  | 		"bad expiration": { | ||||||
|  | 			client: fakeClient{}, | ||||||
|  | 			req: NewUserRequest{ | ||||||
|  | 				Password:   "njkvcb8y934u90grsnkjl", | ||||||
|  | 				Expiration: invalidExpiration, | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNotNil, | ||||||
|  | 		}, | ||||||
|  | 		"database error": { | ||||||
|  | 			client: fakeClient{ | ||||||
|  | 				newUserErr: errors.New("new user error"), | ||||||
|  | 			}, | ||||||
|  | 			req: NewUserRequest{ | ||||||
|  | 				Password:   "njkvcb8y934u90grsnkjl", | ||||||
|  | 				Expiration: time.Now(), | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNotNil, | ||||||
|  | 		}, | ||||||
|  | 		"plugin shut down": { | ||||||
|  | 			client: fakeClient{ | ||||||
|  | 				newUserErr: errors.New("new user error"), | ||||||
|  | 			}, | ||||||
|  | 			req: NewUserRequest{ | ||||||
|  | 				Password:   "njkvcb8y934u90grsnkjl", | ||||||
|  | 				Expiration: time.Now(), | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   cancelledCtx, | ||||||
|  | 			assertErr: assertErrEquals(ErrPluginShutdown), | ||||||
|  | 		}, | ||||||
|  | 		"happy path": { | ||||||
|  | 			client: fakeClient{ | ||||||
|  | 				newUserResp: &proto.NewUserResponse{ | ||||||
|  | 					Username: "new_user", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			req: NewUserRequest{ | ||||||
|  | 				Password:   "njkvcb8y934u90grsnkjl", | ||||||
|  | 				Expiration: time.Now(), | ||||||
|  | 			}, | ||||||
|  | 			doneCtx: runningCtx, | ||||||
|  | 			expectedResp: NewUserResponse{ | ||||||
|  | 				Username: "new_user", | ||||||
|  | 			}, | ||||||
|  | 			assertErr: assertErrNil, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for name, test := range tests { | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			c := gRPCClient{ | ||||||
|  | 				client:  test.client, | ||||||
|  | 				doneCtx: test.doneCtx, | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			ctx := context.Background() | ||||||
|  |  | ||||||
|  | 			resp, err := c.NewUser(ctx, test.req) | ||||||
|  | 			test.assertErr(t, err) | ||||||
|  |  | ||||||
|  | 			if !reflect.DeepEqual(resp, test.expectedResp) { | ||||||
|  | 				t.Fatalf("Actual response: %#v\nExpected response: %#v", resp, test.expectedResp) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestGRPCClient_UpdateUser(t *testing.T) { | ||||||
|  | 	runningCtx := context.Background() | ||||||
|  | 	cancelledCtx, cancel := context.WithCancel(context.Background()) | ||||||
|  | 	cancel() | ||||||
|  |  | ||||||
|  | 	type testCase struct { | ||||||
|  | 		client    proto.DatabaseClient | ||||||
|  | 		req       UpdateUserRequest | ||||||
|  | 		doneCtx   context.Context | ||||||
|  | 		assertErr errorAssertion | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tests := map[string]testCase{ | ||||||
|  | 		"missing username": { | ||||||
|  | 			client:    fakeClient{}, | ||||||
|  | 			req:       UpdateUserRequest{}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNotNil, | ||||||
|  | 		}, | ||||||
|  | 		"missing changes": { | ||||||
|  | 			client: fakeClient{}, | ||||||
|  | 			req: UpdateUserRequest{ | ||||||
|  | 				Username: "user", | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNotNil, | ||||||
|  | 		}, | ||||||
|  | 		"empty password": { | ||||||
|  | 			client: fakeClient{}, | ||||||
|  | 			req: UpdateUserRequest{ | ||||||
|  | 				Username: "user", | ||||||
|  | 				Password: &ChangePassword{ | ||||||
|  | 					NewPassword: "", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNotNil, | ||||||
|  | 		}, | ||||||
|  | 		"zero expiration": { | ||||||
|  | 			client: fakeClient{}, | ||||||
|  | 			req: UpdateUserRequest{ | ||||||
|  | 				Username: "user", | ||||||
|  | 				Expiration: &ChangeExpiration{ | ||||||
|  | 					NewExpiration: time.Time{}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNotNil, | ||||||
|  | 		}, | ||||||
|  | 		"bad expiration": { | ||||||
|  | 			client: fakeClient{}, | ||||||
|  | 			req: UpdateUserRequest{ | ||||||
|  | 				Username: "user", | ||||||
|  | 				Expiration: &ChangeExpiration{ | ||||||
|  | 					NewExpiration: invalidExpiration, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNotNil, | ||||||
|  | 		}, | ||||||
|  | 		"database error": { | ||||||
|  | 			client: fakeClient{ | ||||||
|  | 				updateUserErr: errors.New("update user error"), | ||||||
|  | 			}, | ||||||
|  | 			req: UpdateUserRequest{ | ||||||
|  | 				Username: "user", | ||||||
|  | 				Password: &ChangePassword{ | ||||||
|  | 					NewPassword: "asdf", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNotNil, | ||||||
|  | 		}, | ||||||
|  | 		"plugin shut down": { | ||||||
|  | 			client: fakeClient{ | ||||||
|  | 				updateUserErr: errors.New("update user error"), | ||||||
|  | 			}, | ||||||
|  | 			req: UpdateUserRequest{ | ||||||
|  | 				Username: "user", | ||||||
|  | 				Password: &ChangePassword{ | ||||||
|  | 					NewPassword: "asdf", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   cancelledCtx, | ||||||
|  | 			assertErr: assertErrEquals(ErrPluginShutdown), | ||||||
|  | 		}, | ||||||
|  | 		"happy path - change password": { | ||||||
|  | 			client: fakeClient{}, | ||||||
|  | 			req: UpdateUserRequest{ | ||||||
|  | 				Username: "user", | ||||||
|  | 				Password: &ChangePassword{ | ||||||
|  | 					NewPassword: "asdf", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNil, | ||||||
|  | 		}, | ||||||
|  | 		"happy path - change expiration": { | ||||||
|  | 			client: fakeClient{}, | ||||||
|  | 			req: UpdateUserRequest{ | ||||||
|  | 				Username: "user", | ||||||
|  | 				Expiration: &ChangeExpiration{ | ||||||
|  | 					NewExpiration: time.Now(), | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNil, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for name, test := range tests { | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			c := gRPCClient{ | ||||||
|  | 				client:  test.client, | ||||||
|  | 				doneCtx: test.doneCtx, | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			ctx := context.Background() | ||||||
|  |  | ||||||
|  | 			_, err := c.UpdateUser(ctx, test.req) | ||||||
|  | 			test.assertErr(t, err) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestGRPCClient_DeleteUser(t *testing.T) { | ||||||
|  | 	runningCtx := context.Background() | ||||||
|  | 	cancelledCtx, cancel := context.WithCancel(context.Background()) | ||||||
|  | 	cancel() | ||||||
|  |  | ||||||
|  | 	type testCase struct { | ||||||
|  | 		client    proto.DatabaseClient | ||||||
|  | 		req       DeleteUserRequest | ||||||
|  | 		doneCtx   context.Context | ||||||
|  | 		assertErr errorAssertion | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tests := map[string]testCase{ | ||||||
|  | 		"missing username": { | ||||||
|  | 			client:    fakeClient{}, | ||||||
|  | 			req:       DeleteUserRequest{}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNotNil, | ||||||
|  | 		}, | ||||||
|  | 		"database error": { | ||||||
|  | 			client: fakeClient{ | ||||||
|  | 				deleteUserErr: errors.New("delete user error'"), | ||||||
|  | 			}, | ||||||
|  | 			req: DeleteUserRequest{ | ||||||
|  | 				Username: "user", | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNotNil, | ||||||
|  | 		}, | ||||||
|  | 		"plugin shut down": { | ||||||
|  | 			client: fakeClient{ | ||||||
|  | 				deleteUserErr: errors.New("delete user error'"), | ||||||
|  | 			}, | ||||||
|  | 			req: DeleteUserRequest{ | ||||||
|  | 				Username: "user", | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   cancelledCtx, | ||||||
|  | 			assertErr: assertErrEquals(ErrPluginShutdown), | ||||||
|  | 		}, | ||||||
|  | 		"happy path": { | ||||||
|  | 			client: fakeClient{}, | ||||||
|  | 			req: DeleteUserRequest{ | ||||||
|  | 				Username: "user", | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNil, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for name, test := range tests { | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			c := gRPCClient{ | ||||||
|  | 				client:  test.client, | ||||||
|  | 				doneCtx: test.doneCtx, | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			ctx := context.Background() | ||||||
|  |  | ||||||
|  | 			_, err := c.DeleteUser(ctx, test.req) | ||||||
|  | 			test.assertErr(t, err) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestGRPCClient_Type(t *testing.T) { | ||||||
|  | 	runningCtx := context.Background() | ||||||
|  | 	cancelledCtx, cancel := context.WithCancel(context.Background()) | ||||||
|  | 	cancel() | ||||||
|  |  | ||||||
|  | 	type testCase struct { | ||||||
|  | 		client       proto.DatabaseClient | ||||||
|  | 		doneCtx      context.Context | ||||||
|  | 		expectedType string | ||||||
|  | 		assertErr    errorAssertion | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tests := map[string]testCase{ | ||||||
|  | 		"database error": { | ||||||
|  | 			client: fakeClient{ | ||||||
|  | 				typeErr: errors.New("type error"), | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNotNil, | ||||||
|  | 		}, | ||||||
|  | 		"plugin shut down": { | ||||||
|  | 			client: fakeClient{ | ||||||
|  | 				typeErr: errors.New("type error"), | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   cancelledCtx, | ||||||
|  | 			assertErr: assertErrEquals(ErrPluginShutdown), | ||||||
|  | 		}, | ||||||
|  | 		"happy path": { | ||||||
|  | 			client: fakeClient{ | ||||||
|  | 				typeResp: &proto.TypeResponse{ | ||||||
|  | 					Type: "test type", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:      runningCtx, | ||||||
|  | 			expectedType: "test type", | ||||||
|  | 			assertErr:    assertErrNil, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for name, test := range tests { | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			c := gRPCClient{ | ||||||
|  | 				client:  test.client, | ||||||
|  | 				doneCtx: test.doneCtx, | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			dbType, err := c.Type() | ||||||
|  | 			test.assertErr(t, err) | ||||||
|  |  | ||||||
|  | 			if dbType != test.expectedType { | ||||||
|  | 				t.Fatalf("Actual type: %s Expected type: %s", dbType, test.expectedType) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestGRPCClient_Close(t *testing.T) { | ||||||
|  | 	runningCtx := context.Background() | ||||||
|  | 	cancelledCtx, cancel := context.WithCancel(context.Background()) | ||||||
|  | 	cancel() | ||||||
|  |  | ||||||
|  | 	type testCase struct { | ||||||
|  | 		client    proto.DatabaseClient | ||||||
|  | 		doneCtx   context.Context | ||||||
|  | 		assertErr errorAssertion | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tests := map[string]testCase{ | ||||||
|  | 		"database error": { | ||||||
|  | 			client: fakeClient{ | ||||||
|  | 				typeErr: errors.New("type error"), | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNotNil, | ||||||
|  | 		}, | ||||||
|  | 		"plugin shut down": { | ||||||
|  | 			client: fakeClient{ | ||||||
|  | 				typeErr: errors.New("type error"), | ||||||
|  | 			}, | ||||||
|  | 			doneCtx:   cancelledCtx, | ||||||
|  | 			assertErr: assertErrEquals(ErrPluginShutdown), | ||||||
|  | 		}, | ||||||
|  | 		"happy path": { | ||||||
|  | 			client:    fakeClient{}, | ||||||
|  | 			doneCtx:   runningCtx, | ||||||
|  | 			assertErr: assertErrNil, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for name, test := range tests { | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			c := gRPCClient{ | ||||||
|  | 				client:  test.client, | ||||||
|  | 				doneCtx: test.doneCtx, | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			err := c.Close() | ||||||
|  | 			test.assertErr(t, err) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type errorAssertion func(*testing.T, error) | ||||||
|  |  | ||||||
|  | func assertErrNotNil(t *testing.T, err error) { | ||||||
|  | 	t.Helper() | ||||||
|  | 	if err == nil { | ||||||
|  | 		t.Fatalf("err expected, got nil") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func assertErrNil(t *testing.T, err error) { | ||||||
|  | 	t.Helper() | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("no error expected, got: %s", err) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func assertErrEquals(expectedErr error) errorAssertion { | ||||||
|  | 	return func(t *testing.T, err error) { | ||||||
|  | 		t.Helper() | ||||||
|  | 		if err != expectedErr { | ||||||
|  | 			t.Fatalf("Actual err: %#v Expected err: %#v", err, expectedErr) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var _ proto.DatabaseClient = fakeClient{} | ||||||
|  |  | ||||||
|  | type fakeClient struct { | ||||||
|  | 	initResp *proto.InitializeResponse | ||||||
|  | 	initErr  error | ||||||
|  |  | ||||||
|  | 	newUserResp *proto.NewUserResponse | ||||||
|  | 	newUserErr  error | ||||||
|  |  | ||||||
|  | 	updateUserResp *proto.UpdateUserResponse | ||||||
|  | 	updateUserErr  error | ||||||
|  |  | ||||||
|  | 	deleteUserResp *proto.DeleteUserResponse | ||||||
|  | 	deleteUserErr  error | ||||||
|  |  | ||||||
|  | 	typeResp *proto.TypeResponse | ||||||
|  | 	typeErr  error | ||||||
|  |  | ||||||
|  | 	closeErr error | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f fakeClient) Initialize(context.Context, *proto.InitializeRequest, ...grpc.CallOption) (*proto.InitializeResponse, error) { | ||||||
|  | 	return f.initResp, f.initErr | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f fakeClient) NewUser(context.Context, *proto.NewUserRequest, ...grpc.CallOption) (*proto.NewUserResponse, error) { | ||||||
|  | 	return f.newUserResp, f.newUserErr | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f fakeClient) UpdateUser(context.Context, *proto.UpdateUserRequest, ...grpc.CallOption) (*proto.UpdateUserResponse, error) { | ||||||
|  | 	return f.updateUserResp, f.updateUserErr | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f fakeClient) DeleteUser(context.Context, *proto.DeleteUserRequest, ...grpc.CallOption) (*proto.DeleteUserResponse, error) { | ||||||
|  | 	return f.deleteUserResp, f.deleteUserErr | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f fakeClient) Type(context.Context, *proto.Empty, ...grpc.CallOption) (*proto.TypeResponse, error) { | ||||||
|  | 	return f.typeResp, f.typeErr | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f fakeClient) Close(context.Context, *proto.Empty, ...grpc.CallOption) (*proto.Empty, error) { | ||||||
|  | 	return &proto.Empty{}, f.typeErr | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								sdk/database/dbplugin/v5/grpc_database_plugin.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								sdk/database/dbplugin/v5/grpc_database_plugin.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/go-plugin" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
|  | 	"google.golang.org/grpc" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // handshakeConfigs are used to just do a basic handshake between | ||||||
|  | // a plugin and host. If the handshake fails, a user friendly error is shown. | ||||||
|  | // This prevents users from executing bad plugins or executing a plugin | ||||||
|  | // directory. It is a UX feature, not a security feature. | ||||||
|  | var handshakeConfig = plugin.HandshakeConfig{ | ||||||
|  | 	ProtocolVersion:  5, | ||||||
|  | 	MagicCookieKey:   "VAULT_DATABASE_PLUGIN", | ||||||
|  | 	MagicCookieValue: "926a0820-aea2-be28-51d6-83cdf00e8edb", | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type GRPCDatabasePlugin struct { | ||||||
|  | 	Impl Database | ||||||
|  |  | ||||||
|  | 	// Embeding this will disable the netRPC protocol | ||||||
|  | 	plugin.NetRPCUnsupportedPlugin | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var _ plugin.Plugin = &GRPCDatabasePlugin{} | ||||||
|  | var _ plugin.GRPCPlugin = &GRPCDatabasePlugin{} | ||||||
|  |  | ||||||
|  | func (d GRPCDatabasePlugin) GRPCServer(_ *plugin.GRPCBroker, s *grpc.Server) error { | ||||||
|  | 	proto.RegisterDatabaseServer(s, gRPCServer{impl: d.Impl}) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (GRPCDatabasePlugin) GRPCClient(doneCtx context.Context, _ *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) { | ||||||
|  | 	client := gRPCClient{ | ||||||
|  | 		client:  proto.NewDatabaseClient(c), | ||||||
|  | 		doneCtx: doneCtx, | ||||||
|  | 	} | ||||||
|  | 	return client, nil | ||||||
|  | } | ||||||
							
								
								
									
										190
									
								
								sdk/database/dbplugin/v5/grpc_server.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								sdk/database/dbplugin/v5/grpc_server.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,190 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/golang/protobuf/ptypes" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
|  | 	"google.golang.org/grpc/codes" | ||||||
|  | 	"google.golang.org/grpc/status" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var _ proto.DatabaseServer = gRPCServer{} | ||||||
|  |  | ||||||
|  | type gRPCServer struct { | ||||||
|  | 	impl Database | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Initialize the database plugin | ||||||
|  | func (g gRPCServer) Initialize(ctx context.Context, request *proto.InitializeRequest) (*proto.InitializeResponse, error) { | ||||||
|  | 	rawConfig := structToMap(request.ConfigData) | ||||||
|  |  | ||||||
|  | 	dbReq := InitializeRequest{ | ||||||
|  | 		Config:           rawConfig, | ||||||
|  | 		VerifyConnection: request.VerifyConnection, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dbResp, err := g.impl.Initialize(ctx, dbReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.InitializeResponse{}, status.Errorf(codes.Internal, "failed to initialize: %s", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	newConfig, err := mapToStruct(dbResp.Config) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.InitializeResponse{}, status.Errorf(codes.Internal, "failed to marshal new config to JSON: %s", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	resp := &proto.InitializeResponse{ | ||||||
|  | 		ConfigData: newConfig, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return resp, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (g gRPCServer) NewUser(ctx context.Context, req *proto.NewUserRequest) (*proto.NewUserResponse, error) { | ||||||
|  | 	if req.GetUsernameConfig() == nil { | ||||||
|  | 		return &proto.NewUserResponse{}, status.Errorf(codes.InvalidArgument, "missing username config") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var expiration time.Time | ||||||
|  |  | ||||||
|  | 	if req.GetExpiration() != nil { | ||||||
|  | 		exp, err := ptypes.Timestamp(req.GetExpiration()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return &proto.NewUserResponse{}, status.Errorf(codes.InvalidArgument, "unable to parse expiration date: %s", err) | ||||||
|  | 		} | ||||||
|  | 		expiration = exp | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dbReq := NewUserRequest{ | ||||||
|  | 		UsernameConfig: UsernameMetadata{ | ||||||
|  | 			DisplayName: req.GetUsernameConfig().GetDisplayName(), | ||||||
|  | 			RoleName:    req.GetUsernameConfig().GetRoleName(), | ||||||
|  | 		}, | ||||||
|  | 		Password:           req.GetPassword(), | ||||||
|  | 		Expiration:         expiration, | ||||||
|  | 		Statements:         getStatementsFromProto(req.GetStatements()), | ||||||
|  | 		RollbackStatements: getStatementsFromProto(req.GetRollbackStatements()), | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dbResp, err := g.impl.NewUser(ctx, dbReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.NewUserResponse{}, status.Errorf(codes.Internal, "unable to create new user: %s", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	resp := &proto.NewUserResponse{ | ||||||
|  | 		Username: dbResp.Username, | ||||||
|  | 	} | ||||||
|  | 	return resp, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (g gRPCServer) UpdateUser(ctx context.Context, req *proto.UpdateUserRequest) (*proto.UpdateUserResponse, error) { | ||||||
|  | 	if req.GetUsername() == "" { | ||||||
|  | 		return &proto.UpdateUserResponse{}, status.Errorf(codes.InvalidArgument, "no username provided") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dbReq, err := getUpdateUserRequest(req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.UpdateUserResponse{}, status.Errorf(codes.InvalidArgument, err.Error()) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	_, err = g.impl.UpdateUser(ctx, dbReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.UpdateUserResponse{}, status.Errorf(codes.Internal, "unable to update user: %s", err) | ||||||
|  | 	} | ||||||
|  | 	return &proto.UpdateUserResponse{}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func getUpdateUserRequest(req *proto.UpdateUserRequest) (UpdateUserRequest, error) { | ||||||
|  | 	var password *ChangePassword | ||||||
|  | 	if req.GetPassword() != nil && req.GetPassword().GetNewPassword() != "" { | ||||||
|  | 		password = &ChangePassword{ | ||||||
|  | 			NewPassword: req.GetPassword().GetNewPassword(), | ||||||
|  | 			Statements:  getStatementsFromProto(req.GetPassword().GetStatements()), | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var expiration *ChangeExpiration | ||||||
|  | 	if req.GetExpiration() != nil && req.GetExpiration().GetNewExpiration() != nil { | ||||||
|  | 		newExpiration, err := ptypes.Timestamp(req.GetExpiration().GetNewExpiration()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return UpdateUserRequest{}, fmt.Errorf("unable to parse new expiration: %w", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		expiration = &ChangeExpiration{ | ||||||
|  | 			NewExpiration: newExpiration, | ||||||
|  | 			Statements:    getStatementsFromProto(req.GetExpiration().GetStatements()), | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dbReq := UpdateUserRequest{ | ||||||
|  | 		Username:   req.GetUsername(), | ||||||
|  | 		Password:   password, | ||||||
|  | 		Expiration: expiration, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if !hasChange(dbReq) { | ||||||
|  | 		return UpdateUserRequest{}, fmt.Errorf("update user request has no changes") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return dbReq, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func hasChange(dbReq UpdateUserRequest) bool { | ||||||
|  | 	if dbReq.Password != nil && dbReq.Password.NewPassword != "" { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 	if dbReq.Expiration != nil && !dbReq.Expiration.NewExpiration.IsZero() { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (g gRPCServer) DeleteUser(ctx context.Context, req *proto.DeleteUserRequest) (*proto.DeleteUserResponse, error) { | ||||||
|  | 	if req.GetUsername() == "" { | ||||||
|  | 		return &proto.DeleteUserResponse{}, status.Errorf(codes.InvalidArgument, "no username provided") | ||||||
|  | 	} | ||||||
|  | 	dbReq := DeleteUserRequest{ | ||||||
|  | 		Username:   req.GetUsername(), | ||||||
|  | 		Statements: getStatementsFromProto(req.GetStatements()), | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	_, err := g.impl.DeleteUser(ctx, dbReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.DeleteUserResponse{}, status.Errorf(codes.Internal, "unable to delete user: %s", err) | ||||||
|  | 	} | ||||||
|  | 	return &proto.DeleteUserResponse{}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (g gRPCServer) Type(ctx context.Context, _ *proto.Empty) (*proto.TypeResponse, error) { | ||||||
|  | 	t, err := g.impl.Type() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.TypeResponse{}, status.Errorf(codes.Internal, "unable to retrieve type: %s", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	resp := &proto.TypeResponse{ | ||||||
|  | 		Type: t, | ||||||
|  | 	} | ||||||
|  | 	return resp, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (g gRPCServer) Close(ctx context.Context, _ *proto.Empty) (*proto.Empty, error) { | ||||||
|  | 	err := g.impl.Close() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.Empty{}, status.Errorf(codes.Internal, "unable to close database plugin: %s", err) | ||||||
|  | 	} | ||||||
|  | 	return &proto.Empty{}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func getStatementsFromProto(protoStmts *proto.Statements) (statements Statements) { | ||||||
|  | 	if protoStmts == nil { | ||||||
|  | 		return statements | ||||||
|  | 	} | ||||||
|  | 	cmds := protoStmts.GetCommands() | ||||||
|  | 	statements = Statements{ | ||||||
|  | 		Commands: cmds, | ||||||
|  | 	} | ||||||
|  | 	return statements | ||||||
|  | } | ||||||
							
								
								
									
										692
									
								
								sdk/database/dbplugin/v5/grpc_server_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										692
									
								
								sdk/database/dbplugin/v5/grpc_server_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,692 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"reflect" | ||||||
|  | 	"testing" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"google.golang.org/protobuf/types/known/structpb" | ||||||
|  |  | ||||||
|  | 	"github.com/golang/protobuf/ptypes" | ||||||
|  | 	"github.com/golang/protobuf/ptypes/timestamp" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
|  | 	"google.golang.org/grpc/codes" | ||||||
|  | 	"google.golang.org/grpc/status" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	// Before minValidSeconds in ptypes package | ||||||
|  | 	invalidExpiration = time.Date(0, 1, 1, 0, 0, 0, 0, time.UTC) | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestGRPCServer_Initialize(t *testing.T) { | ||||||
|  | 	type testCase struct { | ||||||
|  | 		db           Database | ||||||
|  | 		req          *proto.InitializeRequest | ||||||
|  | 		expectedResp *proto.InitializeResponse | ||||||
|  | 		expectErr    bool | ||||||
|  | 		expectCode   codes.Code | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tests := map[string]testCase{ | ||||||
|  | 		"database errored": { | ||||||
|  | 			db: fakeDatabase{ | ||||||
|  | 				initErr: errors.New("initialization error"), | ||||||
|  | 			}, | ||||||
|  | 			req:          &proto.InitializeRequest{}, | ||||||
|  | 			expectedResp: &proto.InitializeResponse{}, | ||||||
|  | 			expectErr:    true, | ||||||
|  | 			expectCode:   codes.Internal, | ||||||
|  | 		}, | ||||||
|  | 		"newConfig can't marshal to JSON": { | ||||||
|  | 			db: fakeDatabase{ | ||||||
|  | 				initResp: InitializeResponse{ | ||||||
|  | 					Config: map[string]interface{}{ | ||||||
|  | 						"bad-data": badJSONValue{}, | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			req:          &proto.InitializeRequest{}, | ||||||
|  | 			expectedResp: &proto.InitializeResponse{}, | ||||||
|  | 			expectErr:    true, | ||||||
|  | 			expectCode:   codes.Internal, | ||||||
|  | 		}, | ||||||
|  | 		"happy path with config data": { | ||||||
|  | 			db: fakeDatabase{ | ||||||
|  | 				initResp: InitializeResponse{ | ||||||
|  | 					Config: map[string]interface{}{ | ||||||
|  | 						"foo": "bar", | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			req: &proto.InitializeRequest{ | ||||||
|  | 				ConfigData: marshal(t, map[string]interface{}{ | ||||||
|  | 					"foo": "bar", | ||||||
|  | 				}), | ||||||
|  | 			}, | ||||||
|  | 			expectedResp: &proto.InitializeResponse{ | ||||||
|  | 				ConfigData: marshal(t, map[string]interface{}{ | ||||||
|  | 					"foo": "bar", | ||||||
|  | 				}), | ||||||
|  | 			}, | ||||||
|  | 			expectErr:  false, | ||||||
|  | 			expectCode: codes.OK, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for name, test := range tests { | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			g := gRPCServer{ | ||||||
|  | 				impl: test.db, | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// Context doesn't need to timeout since this is just passed through | ||||||
|  | 			ctx := context.Background() | ||||||
|  |  | ||||||
|  | 			resp, err := g.Initialize(ctx, test.req) | ||||||
|  | 			if test.expectErr && err == nil { | ||||||
|  | 				t.Fatalf("err expected, got nil") | ||||||
|  | 			} | ||||||
|  | 			if !test.expectErr && err != nil { | ||||||
|  | 				t.Fatalf("no error expected, got: %s", err) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			actualCode := status.Code(err) | ||||||
|  | 			if actualCode != test.expectCode { | ||||||
|  | 				t.Fatalf("Actual code: %s Expected code: %s", actualCode, test.expectCode) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if !reflect.DeepEqual(resp, test.expectedResp) { | ||||||
|  | 				t.Fatalf("Actual response: %#v\nExpected response: %#v", resp, test.expectedResp) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestCoerceFloatsToInt(t *testing.T) { | ||||||
|  | 	type testCase struct { | ||||||
|  | 		input    map[string]interface{} | ||||||
|  | 		expected map[string]interface{} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tests := map[string]testCase{ | ||||||
|  | 		"no numbers": { | ||||||
|  | 			input: map[string]interface{}{ | ||||||
|  | 				"foo": "bar", | ||||||
|  | 			}, | ||||||
|  | 			expected: map[string]interface{}{ | ||||||
|  | 				"foo": "bar", | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		"raw integers": { | ||||||
|  | 			input: map[string]interface{}{ | ||||||
|  | 				"foo": 42, | ||||||
|  | 			}, | ||||||
|  | 			expected: map[string]interface{}{ | ||||||
|  | 				"foo": 42, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		"floats ": { | ||||||
|  | 			input: map[string]interface{}{ | ||||||
|  | 				"foo": 42.2, | ||||||
|  | 			}, | ||||||
|  | 			expected: map[string]interface{}{ | ||||||
|  | 				"foo": 42.2, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		"floats coerced to ints": { | ||||||
|  | 			input: map[string]interface{}{ | ||||||
|  | 				"foo": float64(42), | ||||||
|  | 			}, | ||||||
|  | 			expected: map[string]interface{}{ | ||||||
|  | 				"foo": int64(42), | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for name, test := range tests { | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			actual := copyMap(test.input) | ||||||
|  | 			coerceFloatsToInt(actual) | ||||||
|  | 			if !reflect.DeepEqual(actual, test.expected) { | ||||||
|  | 				t.Fatalf("Actual: %#v\nExpected: %#v", actual, test.expected) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func copyMap(m map[string]interface{}) map[string]interface{} { | ||||||
|  | 	newMap := map[string]interface{}{} | ||||||
|  | 	for k, v := range m { | ||||||
|  | 		newMap[k] = v | ||||||
|  | 	} | ||||||
|  | 	return newMap | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestGRPCServer_NewUser(t *testing.T) { | ||||||
|  | 	type testCase struct { | ||||||
|  | 		db           Database | ||||||
|  | 		req          *proto.NewUserRequest | ||||||
|  | 		expectedResp *proto.NewUserResponse | ||||||
|  | 		expectErr    bool | ||||||
|  | 		expectCode   codes.Code | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tests := map[string]testCase{ | ||||||
|  | 		"missing username config": { | ||||||
|  | 			db:           fakeDatabase{}, | ||||||
|  | 			req:          &proto.NewUserRequest{}, | ||||||
|  | 			expectedResp: &proto.NewUserResponse{}, | ||||||
|  | 			expectErr:    true, | ||||||
|  | 			expectCode:   codes.InvalidArgument, | ||||||
|  | 		}, | ||||||
|  | 		"bad expiration": { | ||||||
|  | 			db: fakeDatabase{}, | ||||||
|  | 			req: &proto.NewUserRequest{ | ||||||
|  | 				UsernameConfig: &proto.UsernameConfig{ | ||||||
|  | 					DisplayName: "dispname", | ||||||
|  | 					RoleName:    "rolename", | ||||||
|  | 				}, | ||||||
|  | 				Expiration: ×tamp.Timestamp{ | ||||||
|  | 					Seconds: invalidExpiration.Unix(), | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			expectedResp: &proto.NewUserResponse{}, | ||||||
|  | 			expectErr:    true, | ||||||
|  | 			expectCode:   codes.InvalidArgument, | ||||||
|  | 		}, | ||||||
|  | 		"database error": { | ||||||
|  | 			db: fakeDatabase{ | ||||||
|  | 				newUserErr: errors.New("new user error"), | ||||||
|  | 			}, | ||||||
|  | 			req: &proto.NewUserRequest{ | ||||||
|  | 				UsernameConfig: &proto.UsernameConfig{ | ||||||
|  | 					DisplayName: "dispname", | ||||||
|  | 					RoleName:    "rolename", | ||||||
|  | 				}, | ||||||
|  | 				Expiration: ptypes.TimestampNow(), | ||||||
|  | 			}, | ||||||
|  | 			expectedResp: &proto.NewUserResponse{}, | ||||||
|  | 			expectErr:    true, | ||||||
|  | 			expectCode:   codes.Internal, | ||||||
|  | 		}, | ||||||
|  | 		"happy path with expiration": { | ||||||
|  | 			db: fakeDatabase{ | ||||||
|  | 				newUserResp: NewUserResponse{ | ||||||
|  | 					Username: "someuser_foo", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			req: &proto.NewUserRequest{ | ||||||
|  | 				UsernameConfig: &proto.UsernameConfig{ | ||||||
|  | 					DisplayName: "dispname", | ||||||
|  | 					RoleName:    "rolename", | ||||||
|  | 				}, | ||||||
|  | 				Expiration: ptypes.TimestampNow(), | ||||||
|  | 			}, | ||||||
|  | 			expectedResp: &proto.NewUserResponse{ | ||||||
|  | 				Username: "someuser_foo", | ||||||
|  | 			}, | ||||||
|  | 			expectErr:  false, | ||||||
|  | 			expectCode: codes.OK, | ||||||
|  | 		}, | ||||||
|  | 		"happy path without expiration": { | ||||||
|  | 			db: fakeDatabase{ | ||||||
|  | 				newUserResp: NewUserResponse{ | ||||||
|  | 					Username: "someuser_foo", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			req: &proto.NewUserRequest{ | ||||||
|  | 				UsernameConfig: &proto.UsernameConfig{ | ||||||
|  | 					DisplayName: "dispname", | ||||||
|  | 					RoleName:    "rolename", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			expectedResp: &proto.NewUserResponse{ | ||||||
|  | 				Username: "someuser_foo", | ||||||
|  | 			}, | ||||||
|  | 			expectErr:  false, | ||||||
|  | 			expectCode: codes.OK, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for name, test := range tests { | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			g := gRPCServer{ | ||||||
|  | 				impl: test.db, | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// Context doesn't need to timeout since this is just passed through | ||||||
|  | 			ctx := context.Background() | ||||||
|  |  | ||||||
|  | 			resp, err := g.NewUser(ctx, test.req) | ||||||
|  | 			if test.expectErr && err == nil { | ||||||
|  | 				t.Fatalf("err expected, got nil") | ||||||
|  | 			} | ||||||
|  | 			if !test.expectErr && err != nil { | ||||||
|  | 				t.Fatalf("no error expected, got: %s", err) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			actualCode := status.Code(err) | ||||||
|  | 			if actualCode != test.expectCode { | ||||||
|  | 				t.Fatalf("Actual code: %s Expected code: %s", actualCode, test.expectCode) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if !reflect.DeepEqual(resp, test.expectedResp) { | ||||||
|  | 				t.Fatalf("Actual response: %#v\nExpected response: %#v", resp, test.expectedResp) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestGRPCServer_UpdateUser(t *testing.T) { | ||||||
|  | 	type testCase struct { | ||||||
|  | 		db           Database | ||||||
|  | 		req          *proto.UpdateUserRequest | ||||||
|  | 		expectedResp *proto.UpdateUserResponse | ||||||
|  | 		expectErr    bool | ||||||
|  | 		expectCode   codes.Code | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tests := map[string]testCase{ | ||||||
|  | 		"missing username": { | ||||||
|  | 			db:           fakeDatabase{}, | ||||||
|  | 			req:          &proto.UpdateUserRequest{}, | ||||||
|  | 			expectedResp: &proto.UpdateUserResponse{}, | ||||||
|  | 			expectErr:    true, | ||||||
|  | 			expectCode:   codes.InvalidArgument, | ||||||
|  | 		}, | ||||||
|  | 		"missing changes": { | ||||||
|  | 			db: fakeDatabase{}, | ||||||
|  | 			req: &proto.UpdateUserRequest{ | ||||||
|  | 				Username: "someuser", | ||||||
|  | 			}, | ||||||
|  | 			expectedResp: &proto.UpdateUserResponse{}, | ||||||
|  | 			expectErr:    true, | ||||||
|  | 			expectCode:   codes.InvalidArgument, | ||||||
|  | 		}, | ||||||
|  | 		"database error": { | ||||||
|  | 			db: fakeDatabase{ | ||||||
|  | 				updateUserErr: errors.New("update user error"), | ||||||
|  | 			}, | ||||||
|  | 			req: &proto.UpdateUserRequest{ | ||||||
|  | 				Username: "someuser", | ||||||
|  | 				Password: &proto.ChangePassword{ | ||||||
|  | 					NewPassword: "90ughaino", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			expectedResp: &proto.UpdateUserResponse{}, | ||||||
|  | 			expectErr:    true, | ||||||
|  | 			expectCode:   codes.Internal, | ||||||
|  | 		}, | ||||||
|  | 		"bad expiration date": { | ||||||
|  | 			db: fakeDatabase{}, | ||||||
|  | 			req: &proto.UpdateUserRequest{ | ||||||
|  | 				Username: "someuser", | ||||||
|  | 				Expiration: &proto.ChangeExpiration{ | ||||||
|  | 					NewExpiration: ×tamp.Timestamp{ | ||||||
|  | 						// Before minValidSeconds in ptypes package | ||||||
|  | 						Seconds: invalidExpiration.Unix(), | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			expectedResp: &proto.UpdateUserResponse{}, | ||||||
|  | 			expectErr:    true, | ||||||
|  | 			expectCode:   codes.InvalidArgument, | ||||||
|  | 		}, | ||||||
|  | 		"change password happy path": { | ||||||
|  | 			db: fakeDatabase{}, | ||||||
|  | 			req: &proto.UpdateUserRequest{ | ||||||
|  | 				Username: "someuser", | ||||||
|  | 				Password: &proto.ChangePassword{ | ||||||
|  | 					NewPassword: "90ughaino", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			expectedResp: &proto.UpdateUserResponse{}, | ||||||
|  | 			expectErr:    false, | ||||||
|  | 			expectCode:   codes.OK, | ||||||
|  | 		}, | ||||||
|  | 		"change expiration happy path": { | ||||||
|  | 			db: fakeDatabase{}, | ||||||
|  | 			req: &proto.UpdateUserRequest{ | ||||||
|  | 				Username: "someuser", | ||||||
|  | 				Expiration: &proto.ChangeExpiration{ | ||||||
|  | 					NewExpiration: ptypes.TimestampNow(), | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			expectedResp: &proto.UpdateUserResponse{}, | ||||||
|  | 			expectErr:    false, | ||||||
|  | 			expectCode:   codes.OK, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for name, test := range tests { | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			g := gRPCServer{ | ||||||
|  | 				impl: test.db, | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// Context doesn't need to timeout since this is just passed through | ||||||
|  | 			ctx := context.Background() | ||||||
|  |  | ||||||
|  | 			resp, err := g.UpdateUser(ctx, test.req) | ||||||
|  | 			if test.expectErr && err == nil { | ||||||
|  | 				t.Fatalf("err expected, got nil") | ||||||
|  | 			} | ||||||
|  | 			if !test.expectErr && err != nil { | ||||||
|  | 				t.Fatalf("no error expected, got: %s", err) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			actualCode := status.Code(err) | ||||||
|  | 			if actualCode != test.expectCode { | ||||||
|  | 				t.Fatalf("Actual code: %s Expected code: %s", actualCode, test.expectCode) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if !reflect.DeepEqual(resp, test.expectedResp) { | ||||||
|  | 				t.Fatalf("Actual response: %#v\nExpected response: %#v", resp, test.expectedResp) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestGRPCServer_DeleteUser(t *testing.T) { | ||||||
|  | 	type testCase struct { | ||||||
|  | 		db           Database | ||||||
|  | 		req          *proto.DeleteUserRequest | ||||||
|  | 		expectedResp *proto.DeleteUserResponse | ||||||
|  | 		expectErr    bool | ||||||
|  | 		expectCode   codes.Code | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tests := map[string]testCase{ | ||||||
|  | 		"missing username": { | ||||||
|  | 			db:           fakeDatabase{}, | ||||||
|  | 			req:          &proto.DeleteUserRequest{}, | ||||||
|  | 			expectedResp: &proto.DeleteUserResponse{}, | ||||||
|  | 			expectErr:    true, | ||||||
|  | 			expectCode:   codes.InvalidArgument, | ||||||
|  | 		}, | ||||||
|  | 		"database error": { | ||||||
|  | 			db: fakeDatabase{ | ||||||
|  | 				deleteUserErr: errors.New("delete user error"), | ||||||
|  | 			}, | ||||||
|  | 			req: &proto.DeleteUserRequest{ | ||||||
|  | 				Username: "someuser", | ||||||
|  | 			}, | ||||||
|  | 			expectedResp: &proto.DeleteUserResponse{}, | ||||||
|  | 			expectErr:    true, | ||||||
|  | 			expectCode:   codes.Internal, | ||||||
|  | 		}, | ||||||
|  | 		"happy path": { | ||||||
|  | 			db: fakeDatabase{}, | ||||||
|  | 			req: &proto.DeleteUserRequest{ | ||||||
|  | 				Username: "someuser", | ||||||
|  | 			}, | ||||||
|  | 			expectedResp: &proto.DeleteUserResponse{}, | ||||||
|  | 			expectErr:    false, | ||||||
|  | 			expectCode:   codes.OK, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for name, test := range tests { | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			g := gRPCServer{ | ||||||
|  | 				impl: test.db, | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// Context doesn't need to timeout since this is just passed through | ||||||
|  | 			ctx := context.Background() | ||||||
|  |  | ||||||
|  | 			resp, err := g.DeleteUser(ctx, test.req) | ||||||
|  | 			if test.expectErr && err == nil { | ||||||
|  | 				t.Fatalf("err expected, got nil") | ||||||
|  | 			} | ||||||
|  | 			if !test.expectErr && err != nil { | ||||||
|  | 				t.Fatalf("no error expected, got: %s", err) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			actualCode := status.Code(err) | ||||||
|  | 			if actualCode != test.expectCode { | ||||||
|  | 				t.Fatalf("Actual code: %s Expected code: %s", actualCode, test.expectCode) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if !reflect.DeepEqual(resp, test.expectedResp) { | ||||||
|  | 				t.Fatalf("Actual response: %#v\nExpected response: %#v", resp, test.expectedResp) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestGRPCServer_Type(t *testing.T) { | ||||||
|  | 	type testCase struct { | ||||||
|  | 		db           Database | ||||||
|  | 		expectedResp *proto.TypeResponse | ||||||
|  | 		expectErr    bool | ||||||
|  | 		expectCode   codes.Code | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tests := map[string]testCase{ | ||||||
|  | 		"database error": { | ||||||
|  | 			db: fakeDatabase{ | ||||||
|  | 				typeErr: errors.New("type error"), | ||||||
|  | 			}, | ||||||
|  | 			expectedResp: &proto.TypeResponse{}, | ||||||
|  | 			expectErr:    true, | ||||||
|  | 			expectCode:   codes.Internal, | ||||||
|  | 		}, | ||||||
|  | 		"happy path": { | ||||||
|  | 			db: fakeDatabase{ | ||||||
|  | 				typeResp: "fake database", | ||||||
|  | 			}, | ||||||
|  | 			expectedResp: &proto.TypeResponse{ | ||||||
|  | 				Type: "fake database", | ||||||
|  | 			}, | ||||||
|  | 			expectErr:  false, | ||||||
|  | 			expectCode: codes.OK, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for name, test := range tests { | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			g := gRPCServer{ | ||||||
|  | 				impl: test.db, | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// Context doesn't need to timeout since this is just passed through | ||||||
|  | 			ctx := context.Background() | ||||||
|  |  | ||||||
|  | 			resp, err := g.Type(ctx, &proto.Empty{}) | ||||||
|  | 			if test.expectErr && err == nil { | ||||||
|  | 				t.Fatalf("err expected, got nil") | ||||||
|  | 			} | ||||||
|  | 			if !test.expectErr && err != nil { | ||||||
|  | 				t.Fatalf("no error expected, got: %s", err) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			actualCode := status.Code(err) | ||||||
|  | 			if actualCode != test.expectCode { | ||||||
|  | 				t.Fatalf("Actual code: %s Expected code: %s", actualCode, test.expectCode) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if !reflect.DeepEqual(resp, test.expectedResp) { | ||||||
|  | 				t.Fatalf("Actual response: %#v\nExpected response: %#v", resp, test.expectedResp) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestGRPCServer_Close(t *testing.T) { | ||||||
|  | 	type testCase struct { | ||||||
|  | 		db         Database | ||||||
|  | 		expectErr  bool | ||||||
|  | 		expectCode codes.Code | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tests := map[string]testCase{ | ||||||
|  | 		"database error": { | ||||||
|  | 			db: fakeDatabase{ | ||||||
|  | 				closeErr: errors.New("close error"), | ||||||
|  | 			}, | ||||||
|  | 			expectErr:  true, | ||||||
|  | 			expectCode: codes.Internal, | ||||||
|  | 		}, | ||||||
|  | 		"happy path": { | ||||||
|  | 			db:         fakeDatabase{}, | ||||||
|  | 			expectErr:  false, | ||||||
|  | 			expectCode: codes.OK, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for name, test := range tests { | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			g := gRPCServer{ | ||||||
|  | 				impl: test.db, | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// Context doesn't need to timeout since this is just passed through | ||||||
|  | 			ctx := context.Background() | ||||||
|  |  | ||||||
|  | 			_, err := g.Close(ctx, &proto.Empty{}) | ||||||
|  | 			if test.expectErr && err == nil { | ||||||
|  | 				t.Fatalf("err expected, got nil") | ||||||
|  | 			} | ||||||
|  | 			if !test.expectErr && err != nil { | ||||||
|  | 				t.Fatalf("no error expected, got: %s", err) | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			actualCode := status.Code(err) | ||||||
|  | 			if actualCode != test.expectCode { | ||||||
|  | 				t.Fatalf("Actual code: %s Expected code: %s", actualCode, test.expectCode) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func marshal(t *testing.T, m map[string]interface{}) *structpb.Struct { | ||||||
|  | 	t.Helper() | ||||||
|  |  | ||||||
|  | 	strct, err := mapToStruct(m) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("unable to marshal to protobuf: %s", err) | ||||||
|  | 	} | ||||||
|  | 	return strct | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type badJSONValue struct{} | ||||||
|  |  | ||||||
|  | func (badJSONValue) MarshalJSON() ([]byte, error) { | ||||||
|  | 	return nil, fmt.Errorf("this cannot be marshalled to JSON") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (badJSONValue) UnmarshalJSON([]byte) error { | ||||||
|  | 	return fmt.Errorf("this cannot be unmarshalled from JSON") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var _ Database = fakeDatabase{} | ||||||
|  |  | ||||||
|  | type fakeDatabase struct { | ||||||
|  | 	initResp InitializeResponse | ||||||
|  | 	initErr  error | ||||||
|  |  | ||||||
|  | 	newUserResp NewUserResponse | ||||||
|  | 	newUserErr  error | ||||||
|  |  | ||||||
|  | 	updateUserResp UpdateUserResponse | ||||||
|  | 	updateUserErr  error | ||||||
|  |  | ||||||
|  | 	deleteUserResp DeleteUserResponse | ||||||
|  | 	deleteUserErr  error | ||||||
|  |  | ||||||
|  | 	typeResp string | ||||||
|  | 	typeErr  error | ||||||
|  |  | ||||||
|  | 	closeErr error | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (e fakeDatabase) Initialize(ctx context.Context, req InitializeRequest) (InitializeResponse, error) { | ||||||
|  | 	return e.initResp, e.initErr | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (e fakeDatabase) NewUser(ctx context.Context, req NewUserRequest) (NewUserResponse, error) { | ||||||
|  | 	return e.newUserResp, e.newUserErr | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (e fakeDatabase) UpdateUser(ctx context.Context, req UpdateUserRequest) (UpdateUserResponse, error) { | ||||||
|  | 	return e.updateUserResp, e.updateUserErr | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (e fakeDatabase) DeleteUser(ctx context.Context, req DeleteUserRequest) (DeleteUserResponse, error) { | ||||||
|  | 	return e.deleteUserResp, e.deleteUserErr | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (e fakeDatabase) Type() (string, error) { | ||||||
|  | 	return e.typeResp, e.typeErr | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (e fakeDatabase) Close() error { | ||||||
|  | 	return e.closeErr | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var _ Database = &recordingDatabase{} | ||||||
|  |  | ||||||
|  | type recordingDatabase struct { | ||||||
|  | 	initializeCalls int | ||||||
|  | 	newUserCalls    int | ||||||
|  | 	updateUserCalls int | ||||||
|  | 	deleteUserCalls int | ||||||
|  | 	typeCalls       int | ||||||
|  | 	closeCalls      int | ||||||
|  |  | ||||||
|  | 	// recordingDatabase can act as middleware so we can record the calls to other test Database implementations | ||||||
|  | 	next Database | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f *recordingDatabase) Initialize(ctx context.Context, req InitializeRequest) (InitializeResponse, error) { | ||||||
|  | 	f.initializeCalls++ | ||||||
|  | 	if f.next == nil { | ||||||
|  | 		return InitializeResponse{}, nil | ||||||
|  | 	} | ||||||
|  | 	return f.next.Initialize(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f *recordingDatabase) NewUser(ctx context.Context, req NewUserRequest) (NewUserResponse, error) { | ||||||
|  | 	f.newUserCalls++ | ||||||
|  | 	if f.next == nil { | ||||||
|  | 		return NewUserResponse{}, nil | ||||||
|  | 	} | ||||||
|  | 	return f.next.NewUser(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f *recordingDatabase) UpdateUser(ctx context.Context, req UpdateUserRequest) (UpdateUserResponse, error) { | ||||||
|  | 	f.updateUserCalls++ | ||||||
|  | 	if f.next == nil { | ||||||
|  | 		return UpdateUserResponse{}, nil | ||||||
|  | 	} | ||||||
|  | 	return f.next.UpdateUser(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f *recordingDatabase) DeleteUser(ctx context.Context, req DeleteUserRequest) (DeleteUserResponse, error) { | ||||||
|  | 	f.deleteUserCalls++ | ||||||
|  | 	if f.next == nil { | ||||||
|  | 		return DeleteUserResponse{}, nil | ||||||
|  | 	} | ||||||
|  | 	return f.next.DeleteUser(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f *recordingDatabase) Type() (string, error) { | ||||||
|  | 	f.typeCalls++ | ||||||
|  | 	if f.next == nil { | ||||||
|  | 		return "recordingDatabase", nil | ||||||
|  | 	} | ||||||
|  | 	return f.next.Type() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (f *recordingDatabase) Close() error { | ||||||
|  | 	f.closeCalls++ | ||||||
|  | 	if f.next == nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return f.next.Close() | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								sdk/database/dbplugin/v5/marshalling.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								sdk/database/dbplugin/v5/marshalling.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"math" | ||||||
|  |  | ||||||
|  | 	"google.golang.org/protobuf/types/known/structpb" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func mapToStruct(m map[string]interface{}) (*structpb.Struct, error) { | ||||||
|  | 	return structpb.NewStruct(m) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func structToMap(strct *structpb.Struct) map[string]interface{} { | ||||||
|  | 	m := strct.AsMap() | ||||||
|  | 	coerceFloatsToInt(m) | ||||||
|  | 	return m | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // coerceFloatsToInt if the floats can be coerced to an integer without losing data | ||||||
|  | func coerceFloatsToInt(m map[string]interface{}) { | ||||||
|  | 	for k, v := range m { | ||||||
|  | 		fVal, ok := v.(float64) | ||||||
|  | 		if !ok { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		if isInt(fVal) { | ||||||
|  | 			m[k] = int64(fVal) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // isInt attempts to determine if the given floating point number could be represented as an integer without losing data | ||||||
|  | // This does not work for very large floats, however in this usage that's okay since we don't expect numbers that large. | ||||||
|  | func isInt(f float64) bool { | ||||||
|  | 	return math.Floor(f) == f | ||||||
|  | } | ||||||
							
								
								
									
										274
									
								
								sdk/database/dbplugin/v5/middleware.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								sdk/database/dbplugin/v5/middleware.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,274 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"errors" | ||||||
|  | 	"net/url" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	metrics "github.com/armon/go-metrics" | ||||||
|  | 	"github.com/hashicorp/errwrap" | ||||||
|  | 	log "github.com/hashicorp/go-hclog" | ||||||
|  | 	"google.golang.org/grpc/status" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // /////////////////////////////////////////////////// | ||||||
|  | // Tracing Middleware | ||||||
|  | // /////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | var _ Database = databaseTracingMiddleware{} | ||||||
|  |  | ||||||
|  | // databaseTracingMiddleware wraps a implementation of Database and executes | ||||||
|  | // trace logging on function call. | ||||||
|  | type databaseTracingMiddleware struct { | ||||||
|  | 	next   Database | ||||||
|  | 	logger log.Logger | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseTracingMiddleware) Initialize(ctx context.Context, req InitializeRequest) (resp InitializeResponse, err error) { | ||||||
|  | 	defer func(then time.Time) { | ||||||
|  | 		mw.logger.Trace("initialize", | ||||||
|  | 			"status", "finished", | ||||||
|  | 			"verify", req.VerifyConnection, | ||||||
|  | 			"err", err, | ||||||
|  | 			"took", time.Since(then)) | ||||||
|  | 	}(time.Now()) | ||||||
|  |  | ||||||
|  | 	mw.logger.Trace("initialize", "status", "started") | ||||||
|  | 	return mw.next.Initialize(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseTracingMiddleware) NewUser(ctx context.Context, req NewUserRequest) (resp NewUserResponse, 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.NewUser(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseTracingMiddleware) UpdateUser(ctx context.Context, req UpdateUserRequest) (resp UpdateUserResponse, err error) { | ||||||
|  | 	defer func(then time.Time) { | ||||||
|  | 		mw.logger.Trace("update user", | ||||||
|  | 			"status", "finished", | ||||||
|  | 			"err", err, | ||||||
|  | 			"took", time.Since(then)) | ||||||
|  | 	}(time.Now()) | ||||||
|  |  | ||||||
|  | 	mw.logger.Trace("update user", "status", "started") | ||||||
|  | 	return mw.next.UpdateUser(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseTracingMiddleware) DeleteUser(ctx context.Context, req DeleteUserRequest) (resp DeleteUserResponse, err error) { | ||||||
|  | 	defer func(then time.Time) { | ||||||
|  | 		mw.logger.Trace("delete user", | ||||||
|  | 			"status", "finished", | ||||||
|  | 			"err", err, | ||||||
|  | 			"took", time.Since(then)) | ||||||
|  | 	}(time.Now()) | ||||||
|  |  | ||||||
|  | 	mw.logger.Trace("delete user", | ||||||
|  | 		"status", "started") | ||||||
|  | 	return mw.next.DeleteUser(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseTracingMiddleware) Type() (string, error) { | ||||||
|  | 	return mw.next.Type() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  | // /////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | var _ Database = databaseMetricsMiddleware{} | ||||||
|  |  | ||||||
|  | // 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) Initialize(ctx context.Context, req InitializeRequest) (resp InitializeResponse, 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.Initialize(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseMetricsMiddleware) NewUser(ctx context.Context, req NewUserRequest) (resp NewUserResponse, err error) { | ||||||
|  | 	defer func(start time.Time) { | ||||||
|  | 		metrics.MeasureSince([]string{"database", "NewUser"}, start) | ||||||
|  | 		metrics.MeasureSince([]string{"database", mw.typeStr, "NewUser"}, start) | ||||||
|  |  | ||||||
|  | 		if err != nil { | ||||||
|  | 			metrics.IncrCounter([]string{"database", "NewUser", "error"}, 1) | ||||||
|  | 			metrics.IncrCounter([]string{"database", mw.typeStr, "NewUser", "error"}, 1) | ||||||
|  | 		} | ||||||
|  | 	}(time.Now()) | ||||||
|  |  | ||||||
|  | 	metrics.IncrCounter([]string{"database", "NewUser"}, 1) | ||||||
|  | 	metrics.IncrCounter([]string{"database", mw.typeStr, "NewUser"}, 1) | ||||||
|  | 	return mw.next.NewUser(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseMetricsMiddleware) UpdateUser(ctx context.Context, req UpdateUserRequest) (resp UpdateUserResponse, err error) { | ||||||
|  | 	defer func(now time.Time) { | ||||||
|  | 		metrics.MeasureSince([]string{"database", "UpdateUser"}, now) | ||||||
|  | 		metrics.MeasureSince([]string{"database", mw.typeStr, "UpdateUser"}, now) | ||||||
|  |  | ||||||
|  | 		if err != nil { | ||||||
|  | 			metrics.IncrCounter([]string{"database", "UpdateUser", "error"}, 1) | ||||||
|  | 			metrics.IncrCounter([]string{"database", mw.typeStr, "UpdateUser", "error"}, 1) | ||||||
|  | 		} | ||||||
|  | 	}(time.Now()) | ||||||
|  |  | ||||||
|  | 	metrics.IncrCounter([]string{"database", "UpdateUser"}, 1) | ||||||
|  | 	metrics.IncrCounter([]string{"database", mw.typeStr, "UpdateUser"}, 1) | ||||||
|  | 	return mw.next.UpdateUser(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseMetricsMiddleware) DeleteUser(ctx context.Context, req DeleteUserRequest) (resp DeleteUserResponse, err error) { | ||||||
|  | 	defer func(now time.Time) { | ||||||
|  | 		metrics.MeasureSince([]string{"database", "DeleteUser"}, now) | ||||||
|  | 		metrics.MeasureSince([]string{"database", mw.typeStr, "DeleteUser"}, now) | ||||||
|  |  | ||||||
|  | 		if err != nil { | ||||||
|  | 			metrics.IncrCounter([]string{"database", "DeleteUser", "error"}, 1) | ||||||
|  | 			metrics.IncrCounter([]string{"database", mw.typeStr, "DeleteUser", "error"}, 1) | ||||||
|  | 		} | ||||||
|  | 	}(time.Now()) | ||||||
|  |  | ||||||
|  | 	metrics.IncrCounter([]string{"database", "DeleteUser"}, 1) | ||||||
|  | 	metrics.IncrCounter([]string{"database", mw.typeStr, "DeleteUser"}, 1) | ||||||
|  | 	return mw.next.DeleteUser(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseMetricsMiddleware) Type() (string, error) { | ||||||
|  | 	return mw.next.Type() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  | // /////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | var _ Database = DatabaseErrorSanitizerMiddleware{} | ||||||
|  |  | ||||||
|  | // DatabaseErrorSanitizerMiddleware wraps an implementation of Databases and | ||||||
|  | // sanitizes returned error messages | ||||||
|  | type DatabaseErrorSanitizerMiddleware struct { | ||||||
|  | 	next      Database | ||||||
|  | 	secretsFn secretsFn | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type secretsFn func() map[string]string | ||||||
|  |  | ||||||
|  | func NewDatabaseErrorSanitizerMiddleware(next Database, secrets secretsFn) DatabaseErrorSanitizerMiddleware { | ||||||
|  | 	return DatabaseErrorSanitizerMiddleware{ | ||||||
|  | 		next:      next, | ||||||
|  | 		secretsFn: secrets, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw DatabaseErrorSanitizerMiddleware) Initialize(ctx context.Context, req InitializeRequest) (resp InitializeResponse, err error) { | ||||||
|  | 	resp, err = mw.next.Initialize(ctx, req) | ||||||
|  | 	return resp, mw.sanitize(err) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw DatabaseErrorSanitizerMiddleware) NewUser(ctx context.Context, req NewUserRequest) (resp NewUserResponse, err error) { | ||||||
|  | 	resp, err = mw.next.NewUser(ctx, req) | ||||||
|  | 	return resp, mw.sanitize(err) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw DatabaseErrorSanitizerMiddleware) UpdateUser(ctx context.Context, req UpdateUserRequest) (UpdateUserResponse, error) { | ||||||
|  | 	resp, err := mw.next.UpdateUser(ctx, req) | ||||||
|  | 	return resp, mw.sanitize(err) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw DatabaseErrorSanitizerMiddleware) DeleteUser(ctx context.Context, req DeleteUserRequest) (DeleteUserResponse, error) { | ||||||
|  | 	resp, err := mw.next.DeleteUser(ctx, req) | ||||||
|  | 	return resp, mw.sanitize(err) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw DatabaseErrorSanitizerMiddleware) Type() (string, error) { | ||||||
|  | 	dbType, err := mw.next.Type() | ||||||
|  | 	return dbType, mw.sanitize(err) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw DatabaseErrorSanitizerMiddleware) Close() (err error) { | ||||||
|  | 	return mw.sanitize(mw.next.Close()) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // sanitize errors by removing any sensitive strings within their messages. This uses | ||||||
|  | // the secretsFn to determine what fields should be sanitized. | ||||||
|  | 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 { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	for find, replace := range mw.secretsFn() { | ||||||
|  | 		if find == "" { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Attempt to keep the status code attached to the | ||||||
|  | 		// error while changing the actual error message | ||||||
|  | 		s, ok := status.FromError(err) | ||||||
|  | 		if ok { | ||||||
|  | 			err = status.Error(s.Code(), strings.Replace(s.Message(), find, replace, -1)) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		err = errors.New(strings.Replace(err.Error(), find, replace, -1)) | ||||||
|  | 	} | ||||||
|  | 	return err | ||||||
|  | } | ||||||
							
								
								
									
										484
									
								
								sdk/database/dbplugin/v5/middleware_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										484
									
								
								sdk/database/dbplugin/v5/middleware_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,484 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"errors" | ||||||
|  | 	"net/url" | ||||||
|  | 	"reflect" | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/go-hclog" | ||||||
|  | 	"google.golang.org/grpc/codes" | ||||||
|  | 	"google.golang.org/grpc/status" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestDatabaseErrorSanitizerMiddleware(t *testing.T) { | ||||||
|  | 	type testCase struct { | ||||||
|  | 		inputErr    error | ||||||
|  | 		secretsFunc func() map[string]string | ||||||
|  |  | ||||||
|  | 		expectedError error | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tests := map[string]testCase{ | ||||||
|  | 		"nil error": { | ||||||
|  | 			inputErr:      nil, | ||||||
|  | 			expectedError: nil, | ||||||
|  | 		}, | ||||||
|  | 		"url error": { | ||||||
|  | 			inputErr:      new(url.Error), | ||||||
|  | 			expectedError: errors.New("unable to parse connection url"), | ||||||
|  | 		}, | ||||||
|  | 		"nil secrets func": { | ||||||
|  | 			inputErr:      errors.New("here is my password: iofsd9473tg"), | ||||||
|  | 			expectedError: errors.New("here is my password: iofsd9473tg"), | ||||||
|  | 		}, | ||||||
|  | 		"secrets with empty string": { | ||||||
|  | 			inputErr:      errors.New("here is my password: iofsd9473tg"), | ||||||
|  | 			secretsFunc:   secretFunc(t, "", ""), | ||||||
|  | 			expectedError: errors.New("here is my password: iofsd9473tg"), | ||||||
|  | 		}, | ||||||
|  | 		"secrets that do not match": { | ||||||
|  | 			inputErr:      errors.New("here is my password: iofsd9473tg"), | ||||||
|  | 			secretsFunc:   secretFunc(t, "asdf", "<redacted>"), | ||||||
|  | 			expectedError: errors.New("here is my password: iofsd9473tg"), | ||||||
|  | 		}, | ||||||
|  | 		"secrets that do match": { | ||||||
|  | 			inputErr:      errors.New("here is my password: iofsd9473tg"), | ||||||
|  | 			secretsFunc:   secretFunc(t, "iofsd9473tg", "<redacted>"), | ||||||
|  | 			expectedError: errors.New("here is my password: <redacted>"), | ||||||
|  | 		}, | ||||||
|  | 		"multiple secrets": { | ||||||
|  | 			inputErr: errors.New("here is my password: iofsd9473tg"), | ||||||
|  | 			secretsFunc: secretFunc(t, | ||||||
|  | 				"iofsd9473tg", "<redacted>", | ||||||
|  | 				"password", "<this was the word password>", | ||||||
|  | 			), | ||||||
|  | 			expectedError: errors.New("here is my <this was the word password>: <redacted>"), | ||||||
|  | 		}, | ||||||
|  | 		"gRPC status error": { | ||||||
|  | 			inputErr:      status.Error(codes.InvalidArgument, "an error with a password iofsd9473tg"), | ||||||
|  | 			secretsFunc:   secretFunc(t, "iofsd9473tg", "<redacted>"), | ||||||
|  | 			expectedError: status.Errorf(codes.InvalidArgument, "an error with a password <redacted>"), | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for name, test := range tests { | ||||||
|  | 		t.Run(name, func(t *testing.T) { | ||||||
|  | 			db := fakeDatabase{} | ||||||
|  | 			mw := NewDatabaseErrorSanitizerMiddleware(db, test.secretsFunc) | ||||||
|  |  | ||||||
|  | 			actualErr := mw.sanitize(test.inputErr) | ||||||
|  | 			if !reflect.DeepEqual(actualErr, test.expectedError) { | ||||||
|  | 				t.Fatalf("Actual error: %s\nExpected error: %s", actualErr, test.expectedError) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	t.Run("Initialize", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{ | ||||||
|  | 			next: fakeDatabase{ | ||||||
|  | 				initErr: errors.New("password: iofsd9473tg with some stuff after it"), | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  | 		mw := DatabaseErrorSanitizerMiddleware{ | ||||||
|  | 			next:      db, | ||||||
|  | 			secretsFn: secretFunc(t, "iofsd9473tg", "<redacted>"), | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		expectedErr := errors.New("password: <redacted> with some stuff after it") | ||||||
|  |  | ||||||
|  | 		_, err := mw.Initialize(context.Background(), InitializeRequest{}) | ||||||
|  | 		if !reflect.DeepEqual(err, expectedErr) { | ||||||
|  | 			t.Fatalf("Actual err: %s\n Expected err: %s", err, expectedErr) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		assertEquals(t, db.initializeCalls, 1) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.typeCalls, 0) | ||||||
|  | 		assertEquals(t, db.closeCalls, 0) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("NewUser", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{ | ||||||
|  | 			next: fakeDatabase{ | ||||||
|  | 				newUserErr: errors.New("password: iofsd9473tg with some stuff after it"), | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  | 		mw := DatabaseErrorSanitizerMiddleware{ | ||||||
|  | 			next:      db, | ||||||
|  | 			secretsFn: secretFunc(t, "iofsd9473tg", "<redacted>"), | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		expectedErr := errors.New("password: <redacted> with some stuff after it") | ||||||
|  |  | ||||||
|  | 		_, err := mw.NewUser(context.Background(), NewUserRequest{}) | ||||||
|  | 		if !reflect.DeepEqual(err, expectedErr) { | ||||||
|  | 			t.Fatalf("Actual err: %s\n Expected err: %s", err, expectedErr) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		assertEquals(t, db.initializeCalls, 0) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 1) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.typeCalls, 0) | ||||||
|  | 		assertEquals(t, db.closeCalls, 0) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("UpdateUser", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{ | ||||||
|  | 			next: fakeDatabase{ | ||||||
|  | 				updateUserErr: errors.New("password: iofsd9473tg with some stuff after it"), | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  | 		mw := DatabaseErrorSanitizerMiddleware{ | ||||||
|  | 			next:      db, | ||||||
|  | 			secretsFn: secretFunc(t, "iofsd9473tg", "<redacted>"), | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		expectedErr := errors.New("password: <redacted> with some stuff after it") | ||||||
|  |  | ||||||
|  | 		_, err := mw.UpdateUser(context.Background(), UpdateUserRequest{}) | ||||||
|  | 		if !reflect.DeepEqual(err, expectedErr) { | ||||||
|  | 			t.Fatalf("Actual err: %s\n Expected err: %s", err, expectedErr) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		assertEquals(t, db.initializeCalls, 0) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 1) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.typeCalls, 0) | ||||||
|  | 		assertEquals(t, db.closeCalls, 0) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("DeleteUser", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{ | ||||||
|  | 			next: fakeDatabase{ | ||||||
|  | 				deleteUserErr: errors.New("password: iofsd9473tg with some stuff after it"), | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  | 		mw := DatabaseErrorSanitizerMiddleware{ | ||||||
|  | 			next:      db, | ||||||
|  | 			secretsFn: secretFunc(t, "iofsd9473tg", "<redacted>"), | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		expectedErr := errors.New("password: <redacted> with some stuff after it") | ||||||
|  |  | ||||||
|  | 		_, err := mw.DeleteUser(context.Background(), DeleteUserRequest{}) | ||||||
|  | 		if !reflect.DeepEqual(err, expectedErr) { | ||||||
|  | 			t.Fatalf("Actual err: %s\n Expected err: %s", err, expectedErr) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		assertEquals(t, db.initializeCalls, 0) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 1) | ||||||
|  | 		assertEquals(t, db.typeCalls, 0) | ||||||
|  | 		assertEquals(t, db.closeCalls, 0) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("Type", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{ | ||||||
|  | 			next: fakeDatabase{ | ||||||
|  | 				typeErr: errors.New("password: iofsd9473tg with some stuff after it"), | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  | 		mw := DatabaseErrorSanitizerMiddleware{ | ||||||
|  | 			next:      db, | ||||||
|  | 			secretsFn: secretFunc(t, "iofsd9473tg", "<redacted>"), | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		expectedErr := errors.New("password: <redacted> with some stuff after it") | ||||||
|  |  | ||||||
|  | 		_, err := mw.Type() | ||||||
|  | 		if !reflect.DeepEqual(err, expectedErr) { | ||||||
|  | 			t.Fatalf("Actual err: %s\n Expected err: %s", err, expectedErr) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		assertEquals(t, db.initializeCalls, 0) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.typeCalls, 1) | ||||||
|  | 		assertEquals(t, db.closeCalls, 0) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("Close", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{ | ||||||
|  | 			next: fakeDatabase{ | ||||||
|  | 				closeErr: errors.New("password: iofsd9473tg with some stuff after it"), | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  | 		mw := DatabaseErrorSanitizerMiddleware{ | ||||||
|  | 			next:      db, | ||||||
|  | 			secretsFn: secretFunc(t, "iofsd9473tg", "<redacted>"), | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		expectedErr := errors.New("password: <redacted> with some stuff after it") | ||||||
|  |  | ||||||
|  | 		err := mw.Close() | ||||||
|  | 		if !reflect.DeepEqual(err, expectedErr) { | ||||||
|  | 			t.Fatalf("Actual err: %s\n Expected err: %s", err, expectedErr) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		assertEquals(t, db.initializeCalls, 0) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.typeCalls, 0) | ||||||
|  | 		assertEquals(t, db.closeCalls, 1) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func secretFunc(t *testing.T, vals ...string) func() map[string]string { | ||||||
|  | 	t.Helper() | ||||||
|  | 	if len(vals)%2 != 0 { | ||||||
|  | 		t.Fatalf("Test configuration error: secretFunc must be called with an even number of values") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	m := map[string]string{} | ||||||
|  |  | ||||||
|  | 	for i := 0; i < len(vals); i += 2 { | ||||||
|  | 		key := vals[i] | ||||||
|  | 		m[key] = vals[i+1] | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return func() map[string]string { | ||||||
|  | 		return m | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestTracingMiddleware(t *testing.T) { | ||||||
|  | 	t.Run("Initialize", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{} | ||||||
|  | 		logger := hclog.NewNullLogger() | ||||||
|  | 		mw := databaseTracingMiddleware{ | ||||||
|  | 			next:   db, | ||||||
|  | 			logger: logger, | ||||||
|  | 		} | ||||||
|  | 		_, err := mw.Initialize(context.Background(), InitializeRequest{}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Expected no error, but got: %s", err) | ||||||
|  | 		} | ||||||
|  | 		assertEquals(t, db.initializeCalls, 1) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.typeCalls, 0) | ||||||
|  | 		assertEquals(t, db.closeCalls, 0) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("NewUser", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{} | ||||||
|  | 		logger := hclog.NewNullLogger() | ||||||
|  | 		mw := databaseTracingMiddleware{ | ||||||
|  | 			next:   db, | ||||||
|  | 			logger: logger, | ||||||
|  | 		} | ||||||
|  | 		_, err := mw.NewUser(context.Background(), NewUserRequest{}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Expected no error, but got: %s", err) | ||||||
|  | 		} | ||||||
|  | 		assertEquals(t, db.initializeCalls, 0) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 1) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.typeCalls, 0) | ||||||
|  | 		assertEquals(t, db.closeCalls, 0) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("UpdateUser", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{} | ||||||
|  | 		logger := hclog.NewNullLogger() | ||||||
|  | 		mw := databaseTracingMiddleware{ | ||||||
|  | 			next:   db, | ||||||
|  | 			logger: logger, | ||||||
|  | 		} | ||||||
|  | 		_, err := mw.UpdateUser(context.Background(), UpdateUserRequest{}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Expected no error, but got: %s", err) | ||||||
|  | 		} | ||||||
|  | 		assertEquals(t, db.initializeCalls, 0) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 1) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.typeCalls, 0) | ||||||
|  | 		assertEquals(t, db.closeCalls, 0) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("DeleteUser", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{} | ||||||
|  | 		logger := hclog.NewNullLogger() | ||||||
|  | 		mw := databaseTracingMiddleware{ | ||||||
|  | 			next:   db, | ||||||
|  | 			logger: logger, | ||||||
|  | 		} | ||||||
|  | 		_, err := mw.DeleteUser(context.Background(), DeleteUserRequest{}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Expected no error, but got: %s", err) | ||||||
|  | 		} | ||||||
|  | 		assertEquals(t, db.initializeCalls, 0) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 1) | ||||||
|  | 		assertEquals(t, db.typeCalls, 0) | ||||||
|  | 		assertEquals(t, db.closeCalls, 0) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("Type", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{} | ||||||
|  | 		logger := hclog.NewNullLogger() | ||||||
|  | 		mw := databaseTracingMiddleware{ | ||||||
|  | 			next:   db, | ||||||
|  | 			logger: logger, | ||||||
|  | 		} | ||||||
|  | 		_, err := mw.Type() | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Expected no error, but got: %s", err) | ||||||
|  | 		} | ||||||
|  | 		assertEquals(t, db.initializeCalls, 0) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.typeCalls, 1) | ||||||
|  | 		assertEquals(t, db.closeCalls, 0) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("Close", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{} | ||||||
|  | 		logger := hclog.NewNullLogger() | ||||||
|  | 		mw := databaseTracingMiddleware{ | ||||||
|  | 			next:   db, | ||||||
|  | 			logger: logger, | ||||||
|  | 		} | ||||||
|  | 		err := mw.Close() | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Expected no error, but got: %s", err) | ||||||
|  | 		} | ||||||
|  | 		assertEquals(t, db.initializeCalls, 0) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.typeCalls, 0) | ||||||
|  | 		assertEquals(t, db.closeCalls, 1) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestMetricsMiddleware(t *testing.T) { | ||||||
|  | 	t.Run("Initialize", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{} | ||||||
|  | 		mw := databaseMetricsMiddleware{ | ||||||
|  | 			next:    db, | ||||||
|  | 			typeStr: "metrics", | ||||||
|  | 		} | ||||||
|  | 		_, err := mw.Initialize(context.Background(), InitializeRequest{}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Expected no error, but got: %s", err) | ||||||
|  | 		} | ||||||
|  | 		assertEquals(t, db.initializeCalls, 1) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.typeCalls, 0) | ||||||
|  | 		assertEquals(t, db.closeCalls, 0) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("NewUser", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{} | ||||||
|  | 		mw := databaseMetricsMiddleware{ | ||||||
|  | 			next:    db, | ||||||
|  | 			typeStr: "metrics", | ||||||
|  | 		} | ||||||
|  | 		_, err := mw.NewUser(context.Background(), NewUserRequest{}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Expected no error, but got: %s", err) | ||||||
|  | 		} | ||||||
|  | 		assertEquals(t, db.initializeCalls, 0) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 1) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.typeCalls, 0) | ||||||
|  | 		assertEquals(t, db.closeCalls, 0) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("UpdateUser", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{} | ||||||
|  | 		mw := databaseMetricsMiddleware{ | ||||||
|  | 			next:    db, | ||||||
|  | 			typeStr: "metrics", | ||||||
|  | 		} | ||||||
|  | 		_, err := mw.UpdateUser(context.Background(), UpdateUserRequest{}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Expected no error, but got: %s", err) | ||||||
|  | 		} | ||||||
|  | 		assertEquals(t, db.initializeCalls, 0) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 1) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.typeCalls, 0) | ||||||
|  | 		assertEquals(t, db.closeCalls, 0) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("DeleteUser", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{} | ||||||
|  | 		mw := databaseMetricsMiddleware{ | ||||||
|  | 			next:    db, | ||||||
|  | 			typeStr: "metrics", | ||||||
|  | 		} | ||||||
|  | 		_, err := mw.DeleteUser(context.Background(), DeleteUserRequest{}) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Expected no error, but got: %s", err) | ||||||
|  | 		} | ||||||
|  | 		assertEquals(t, db.initializeCalls, 0) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 1) | ||||||
|  | 		assertEquals(t, db.typeCalls, 0) | ||||||
|  | 		assertEquals(t, db.closeCalls, 0) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("Type", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{} | ||||||
|  | 		mw := databaseMetricsMiddleware{ | ||||||
|  | 			next:    db, | ||||||
|  | 			typeStr: "metrics", | ||||||
|  | 		} | ||||||
|  | 		_, err := mw.Type() | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Expected no error, but got: %s", err) | ||||||
|  | 		} | ||||||
|  | 		assertEquals(t, db.initializeCalls, 0) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.typeCalls, 1) | ||||||
|  | 		assertEquals(t, db.closeCalls, 0) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	t.Run("Close", func(t *testing.T) { | ||||||
|  | 		db := &recordingDatabase{} | ||||||
|  | 		mw := databaseMetricsMiddleware{ | ||||||
|  | 			next:    db, | ||||||
|  | 			typeStr: "metrics", | ||||||
|  | 		} | ||||||
|  | 		err := mw.Close() | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("Expected no error, but got: %s", err) | ||||||
|  | 		} | ||||||
|  | 		assertEquals(t, db.initializeCalls, 0) | ||||||
|  | 		assertEquals(t, db.newUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.updateUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.deleteUserCalls, 0) | ||||||
|  | 		assertEquals(t, db.typeCalls, 0) | ||||||
|  | 		assertEquals(t, db.closeCalls, 1) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func assertEquals(t *testing.T, actual, expected int) { | ||||||
|  | 	t.Helper() | ||||||
|  | 	if actual != expected { | ||||||
|  | 		t.Fatalf("Actual: %d Expected: %d", actual, expected) | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										81
									
								
								sdk/database/dbplugin/v5/plugin_client.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								sdk/database/dbplugin/v5/plugin_client.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | |||||||
|  | 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{ | ||||||
|  | 		5: plugin.PluginSet{ | ||||||
|  | 			"database": new(GRPCDatabasePlugin), | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	client, err := pluginRunner.RunConfig(ctx, | ||||||
|  | 		pluginutil.Runner(sys), | ||||||
|  | 		pluginutil.PluginSets(pluginSets), | ||||||
|  | 		pluginutil.HandshakeConfig(handshakeConfig), | ||||||
|  | 		pluginutil.Logger(logger), | ||||||
|  | 		pluginutil.MetadataMode(isMetadataMode), | ||||||
|  | 		pluginutil.AutoMTLS(false), | ||||||
|  | 	) | ||||||
|  | 	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 | ||||||
|  | } | ||||||
							
								
								
									
										78
									
								
								sdk/database/dbplugin/v5/plugin_factory.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								sdk/database/dbplugin/v5/plugin_factory.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"fmt" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/errwrap" | ||||||
|  | 	log "github.com/hashicorp/go-hclog" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/helper/consts" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/helper/pluginutil" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // 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 | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								sdk/database/dbplugin/v5/plugin_server.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								sdk/database/dbplugin/v5/plugin_server.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"crypto/tls" | ||||||
|  | 	"fmt" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/go-plugin" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/helper/pluginutil" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // 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 { | ||||||
|  | 	err := pluginutil.OptionallyEnableMlock() | ||||||
|  | 	if err != nil { | ||||||
|  | 		fmt.Println(err) | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// pluginSets is the map of plugins we can dispense. | ||||||
|  | 	pluginSets := map[int]plugin.PluginSet{ | ||||||
|  | 		5: plugin.PluginSet{ | ||||||
|  | 			"database": &GRPCDatabasePlugin{ | ||||||
|  | 				Impl: db, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	conf := &plugin.ServeConfig{ | ||||||
|  | 		HandshakeConfig:  handshakeConfig, | ||||||
|  | 		VersionedPlugins: pluginSets, | ||||||
|  | 		GRPCServer:       plugin.DefaultGRPCServer, | ||||||
|  | 		TLSProvider:      tlsProvider, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return conf | ||||||
|  | } | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| // versions: | // versions: | ||||||
| // 	protoc-gen-go v1.23.0 | // 	protoc-gen-go v1.23.0 | ||||||
| // 	protoc        v3.13.0 | // 	protoc        v3.13.0 | ||||||
| // source: sdk/database/newdbplugin/proto/database.proto | // source: sdk/database/dbplugin/v5/proto/database.proto | ||||||
| 
 | 
 | ||||||
| package proto | package proto | ||||||
| 
 | 
 | ||||||
| @@ -46,7 +46,7 @@ type InitializeRequest struct { | |||||||
| func (x *InitializeRequest) Reset() { | func (x *InitializeRequest) Reset() { | ||||||
| 	*x = InitializeRequest{} | 	*x = InitializeRequest{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[0] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[0] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -59,7 +59,7 @@ func (x *InitializeRequest) String() string { | |||||||
| func (*InitializeRequest) ProtoMessage() {} | func (*InitializeRequest) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *InitializeRequest) ProtoReflect() protoreflect.Message { | func (x *InitializeRequest) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[0] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[0] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -72,7 +72,7 @@ func (x *InitializeRequest) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use InitializeRequest.ProtoReflect.Descriptor instead. | // Deprecated: Use InitializeRequest.ProtoReflect.Descriptor instead. | ||||||
| func (*InitializeRequest) Descriptor() ([]byte, []int) { | func (*InitializeRequest) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{0} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{0} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *InitializeRequest) GetConfigData() *_struct.Struct { | func (x *InitializeRequest) GetConfigData() *_struct.Struct { | ||||||
| @@ -100,7 +100,7 @@ type InitializeResponse struct { | |||||||
| func (x *InitializeResponse) Reset() { | func (x *InitializeResponse) Reset() { | ||||||
| 	*x = InitializeResponse{} | 	*x = InitializeResponse{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[1] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[1] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -113,7 +113,7 @@ func (x *InitializeResponse) String() string { | |||||||
| func (*InitializeResponse) ProtoMessage() {} | func (*InitializeResponse) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *InitializeResponse) ProtoReflect() protoreflect.Message { | func (x *InitializeResponse) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[1] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[1] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -126,7 +126,7 @@ func (x *InitializeResponse) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use InitializeResponse.ProtoReflect.Descriptor instead. | // Deprecated: Use InitializeResponse.ProtoReflect.Descriptor instead. | ||||||
| func (*InitializeResponse) Descriptor() ([]byte, []int) { | func (*InitializeResponse) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{1} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{1} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *InitializeResponse) GetConfigData() *_struct.Struct { | func (x *InitializeResponse) GetConfigData() *_struct.Struct { | ||||||
| @@ -151,7 +151,7 @@ type NewUserRequest struct { | |||||||
| func (x *NewUserRequest) Reset() { | func (x *NewUserRequest) Reset() { | ||||||
| 	*x = NewUserRequest{} | 	*x = NewUserRequest{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[2] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[2] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -164,7 +164,7 @@ func (x *NewUserRequest) String() string { | |||||||
| func (*NewUserRequest) ProtoMessage() {} | func (*NewUserRequest) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *NewUserRequest) ProtoReflect() protoreflect.Message { | func (x *NewUserRequest) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[2] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[2] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -177,7 +177,7 @@ func (x *NewUserRequest) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use NewUserRequest.ProtoReflect.Descriptor instead. | // Deprecated: Use NewUserRequest.ProtoReflect.Descriptor instead. | ||||||
| func (*NewUserRequest) Descriptor() ([]byte, []int) { | func (*NewUserRequest) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{2} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{2} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *NewUserRequest) GetUsernameConfig() *UsernameConfig { | func (x *NewUserRequest) GetUsernameConfig() *UsernameConfig { | ||||||
| @@ -227,7 +227,7 @@ type UsernameConfig struct { | |||||||
| func (x *UsernameConfig) Reset() { | func (x *UsernameConfig) Reset() { | ||||||
| 	*x = UsernameConfig{} | 	*x = UsernameConfig{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[3] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[3] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -240,7 +240,7 @@ func (x *UsernameConfig) String() string { | |||||||
| func (*UsernameConfig) ProtoMessage() {} | func (*UsernameConfig) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *UsernameConfig) ProtoReflect() protoreflect.Message { | func (x *UsernameConfig) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[3] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[3] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -253,7 +253,7 @@ func (x *UsernameConfig) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use UsernameConfig.ProtoReflect.Descriptor instead. | // Deprecated: Use UsernameConfig.ProtoReflect.Descriptor instead. | ||||||
| func (*UsernameConfig) Descriptor() ([]byte, []int) { | func (*UsernameConfig) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{3} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{3} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *UsernameConfig) GetDisplayName() string { | func (x *UsernameConfig) GetDisplayName() string { | ||||||
| @@ -281,7 +281,7 @@ type NewUserResponse struct { | |||||||
| func (x *NewUserResponse) Reset() { | func (x *NewUserResponse) Reset() { | ||||||
| 	*x = NewUserResponse{} | 	*x = NewUserResponse{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[4] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[4] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -294,7 +294,7 @@ func (x *NewUserResponse) String() string { | |||||||
| func (*NewUserResponse) ProtoMessage() {} | func (*NewUserResponse) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *NewUserResponse) ProtoReflect() protoreflect.Message { | func (x *NewUserResponse) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[4] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[4] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -307,7 +307,7 @@ func (x *NewUserResponse) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use NewUserResponse.ProtoReflect.Descriptor instead. | // Deprecated: Use NewUserResponse.ProtoReflect.Descriptor instead. | ||||||
| func (*NewUserResponse) Descriptor() ([]byte, []int) { | func (*NewUserResponse) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{4} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{4} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *NewUserResponse) GetUsername() string { | func (x *NewUserResponse) GetUsername() string { | ||||||
| @@ -333,7 +333,7 @@ type UpdateUserRequest struct { | |||||||
| func (x *UpdateUserRequest) Reset() { | func (x *UpdateUserRequest) Reset() { | ||||||
| 	*x = UpdateUserRequest{} | 	*x = UpdateUserRequest{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[5] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[5] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -346,7 +346,7 @@ func (x *UpdateUserRequest) String() string { | |||||||
| func (*UpdateUserRequest) ProtoMessage() {} | func (*UpdateUserRequest) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *UpdateUserRequest) ProtoReflect() protoreflect.Message { | func (x *UpdateUserRequest) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[5] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[5] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -359,7 +359,7 @@ func (x *UpdateUserRequest) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use UpdateUserRequest.ProtoReflect.Descriptor instead. | // Deprecated: Use UpdateUserRequest.ProtoReflect.Descriptor instead. | ||||||
| func (*UpdateUserRequest) Descriptor() ([]byte, []int) { | func (*UpdateUserRequest) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{5} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{5} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *UpdateUserRequest) GetUsername() string { | func (x *UpdateUserRequest) GetUsername() string { | ||||||
| @@ -395,7 +395,7 @@ type ChangePassword struct { | |||||||
| func (x *ChangePassword) Reset() { | func (x *ChangePassword) Reset() { | ||||||
| 	*x = ChangePassword{} | 	*x = ChangePassword{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[6] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[6] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -408,7 +408,7 @@ func (x *ChangePassword) String() string { | |||||||
| func (*ChangePassword) ProtoMessage() {} | func (*ChangePassword) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *ChangePassword) ProtoReflect() protoreflect.Message { | func (x *ChangePassword) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[6] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[6] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -421,7 +421,7 @@ func (x *ChangePassword) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use ChangePassword.ProtoReflect.Descriptor instead. | // Deprecated: Use ChangePassword.ProtoReflect.Descriptor instead. | ||||||
| func (*ChangePassword) Descriptor() ([]byte, []int) { | func (*ChangePassword) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{6} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{6} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *ChangePassword) GetNewPassword() string { | func (x *ChangePassword) GetNewPassword() string { | ||||||
| @@ -450,7 +450,7 @@ type ChangeExpiration struct { | |||||||
| func (x *ChangeExpiration) Reset() { | func (x *ChangeExpiration) Reset() { | ||||||
| 	*x = ChangeExpiration{} | 	*x = ChangeExpiration{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[7] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[7] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -463,7 +463,7 @@ func (x *ChangeExpiration) String() string { | |||||||
| func (*ChangeExpiration) ProtoMessage() {} | func (*ChangeExpiration) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *ChangeExpiration) ProtoReflect() protoreflect.Message { | func (x *ChangeExpiration) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[7] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[7] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -476,7 +476,7 @@ func (x *ChangeExpiration) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use ChangeExpiration.ProtoReflect.Descriptor instead. | // Deprecated: Use ChangeExpiration.ProtoReflect.Descriptor instead. | ||||||
| func (*ChangeExpiration) Descriptor() ([]byte, []int) { | func (*ChangeExpiration) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{7} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{7} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *ChangeExpiration) GetNewExpiration() *timestamp.Timestamp { | func (x *ChangeExpiration) GetNewExpiration() *timestamp.Timestamp { | ||||||
| @@ -502,7 +502,7 @@ type UpdateUserResponse struct { | |||||||
| func (x *UpdateUserResponse) Reset() { | func (x *UpdateUserResponse) Reset() { | ||||||
| 	*x = UpdateUserResponse{} | 	*x = UpdateUserResponse{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[8] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[8] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -515,7 +515,7 @@ func (x *UpdateUserResponse) String() string { | |||||||
| func (*UpdateUserResponse) ProtoMessage() {} | func (*UpdateUserResponse) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *UpdateUserResponse) ProtoReflect() protoreflect.Message { | func (x *UpdateUserResponse) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[8] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[8] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -528,7 +528,7 @@ func (x *UpdateUserResponse) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use UpdateUserResponse.ProtoReflect.Descriptor instead. | // Deprecated: Use UpdateUserResponse.ProtoReflect.Descriptor instead. | ||||||
| func (*UpdateUserResponse) Descriptor() ([]byte, []int) { | func (*UpdateUserResponse) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{8} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{8} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ///////////////// | ///////////////// | ||||||
| @@ -546,7 +546,7 @@ type DeleteUserRequest struct { | |||||||
| func (x *DeleteUserRequest) Reset() { | func (x *DeleteUserRequest) Reset() { | ||||||
| 	*x = DeleteUserRequest{} | 	*x = DeleteUserRequest{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[9] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[9] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -559,7 +559,7 @@ func (x *DeleteUserRequest) String() string { | |||||||
| func (*DeleteUserRequest) ProtoMessage() {} | func (*DeleteUserRequest) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *DeleteUserRequest) ProtoReflect() protoreflect.Message { | func (x *DeleteUserRequest) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[9] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[9] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -572,7 +572,7 @@ func (x *DeleteUserRequest) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use DeleteUserRequest.ProtoReflect.Descriptor instead. | // Deprecated: Use DeleteUserRequest.ProtoReflect.Descriptor instead. | ||||||
| func (*DeleteUserRequest) Descriptor() ([]byte, []int) { | func (*DeleteUserRequest) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{9} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{9} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *DeleteUserRequest) GetUsername() string { | func (x *DeleteUserRequest) GetUsername() string { | ||||||
| @@ -598,7 +598,7 @@ type DeleteUserResponse struct { | |||||||
| func (x *DeleteUserResponse) Reset() { | func (x *DeleteUserResponse) Reset() { | ||||||
| 	*x = DeleteUserResponse{} | 	*x = DeleteUserResponse{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[10] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[10] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -611,7 +611,7 @@ func (x *DeleteUserResponse) String() string { | |||||||
| func (*DeleteUserResponse) ProtoMessage() {} | func (*DeleteUserResponse) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *DeleteUserResponse) ProtoReflect() protoreflect.Message { | func (x *DeleteUserResponse) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[10] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[10] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -624,7 +624,7 @@ func (x *DeleteUserResponse) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use DeleteUserResponse.ProtoReflect.Descriptor instead. | // Deprecated: Use DeleteUserResponse.ProtoReflect.Descriptor instead. | ||||||
| func (*DeleteUserResponse) Descriptor() ([]byte, []int) { | func (*DeleteUserResponse) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{10} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{10} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ///////////////// | ///////////////// | ||||||
| @@ -641,7 +641,7 @@ type TypeResponse struct { | |||||||
| func (x *TypeResponse) Reset() { | func (x *TypeResponse) Reset() { | ||||||
| 	*x = TypeResponse{} | 	*x = TypeResponse{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[11] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[11] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -654,7 +654,7 @@ func (x *TypeResponse) String() string { | |||||||
| func (*TypeResponse) ProtoMessage() {} | func (*TypeResponse) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *TypeResponse) ProtoReflect() protoreflect.Message { | func (x *TypeResponse) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[11] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[11] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -667,7 +667,7 @@ func (x *TypeResponse) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use TypeResponse.ProtoReflect.Descriptor instead. | // Deprecated: Use TypeResponse.ProtoReflect.Descriptor instead. | ||||||
| func (*TypeResponse) Descriptor() ([]byte, []int) { | func (*TypeResponse) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{11} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{11} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *TypeResponse) GetType() string { | func (x *TypeResponse) GetType() string { | ||||||
| @@ -691,7 +691,7 @@ type Statements struct { | |||||||
| func (x *Statements) Reset() { | func (x *Statements) Reset() { | ||||||
| 	*x = Statements{} | 	*x = Statements{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[12] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[12] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -704,7 +704,7 @@ func (x *Statements) String() string { | |||||||
| func (*Statements) ProtoMessage() {} | func (*Statements) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *Statements) ProtoReflect() protoreflect.Message { | func (x *Statements) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[12] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[12] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -717,7 +717,7 @@ func (x *Statements) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use Statements.ProtoReflect.Descriptor instead. | // Deprecated: Use Statements.ProtoReflect.Descriptor instead. | ||||||
| func (*Statements) Descriptor() ([]byte, []int) { | func (*Statements) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{12} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{12} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *Statements) GetCommands() []string { | func (x *Statements) GetCommands() []string { | ||||||
| @@ -736,7 +736,7 @@ type Empty struct { | |||||||
| func (x *Empty) Reset() { | func (x *Empty) Reset() { | ||||||
| 	*x = Empty{} | 	*x = Empty{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[13] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[13] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -749,7 +749,7 @@ func (x *Empty) String() string { | |||||||
| func (*Empty) ProtoMessage() {} | func (*Empty) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *Empty) ProtoReflect() protoreflect.Message { | func (x *Empty) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[13] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[13] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -762,16 +762,16 @@ func (x *Empty) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use Empty.ProtoReflect.Descriptor instead. | // Deprecated: Use Empty.ProtoReflect.Descriptor instead. | ||||||
| func (*Empty) Descriptor() ([]byte, []int) { | func (*Empty) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{13} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{13} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var File_sdk_database_newdbplugin_proto_database_proto protoreflect.FileDescriptor | var File_sdk_database_dbplugin_v5_proto_database_proto protoreflect.FileDescriptor | ||||||
| 
 | 
 | ||||||
| var file_sdk_database_newdbplugin_proto_database_proto_rawDesc = []byte{ | var file_sdk_database_dbplugin_v5_proto_database_proto_rawDesc = []byte{ | ||||||
| 	0x0a, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x6e, | 	0x0a, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x64, | ||||||
| 	0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, | 	0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, | ||||||
| 	0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, | 	0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, | ||||||
| 	0x0b, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x1a, 0x1c, 0x67, 0x6f, | 	0x0b, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x1a, 0x1c, 0x67, 0x6f, | ||||||
| 	0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, | 	0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, | ||||||
| 	0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, | 	0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, | ||||||
| 	0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, | 	0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, | ||||||
| @@ -791,8 +791,8 @@ var file_sdk_database_newdbplugin_proto_database_proto_rawDesc = []byte{ | |||||||
| 	0x66, 0x69, 0x67, 0x44, 0x61, 0x74, 0x61, 0x22, 0xb1, 0x02, 0x0a, 0x0e, 0x4e, 0x65, 0x77, 0x55, | 	0x66, 0x69, 0x67, 0x44, 0x61, 0x74, 0x61, 0x22, 0xb1, 0x02, 0x0a, 0x0e, 0x4e, 0x65, 0x77, 0x55, | ||||||
| 	0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x0f, 0x75, 0x73, | 	0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x0f, 0x75, 0x73, | ||||||
| 	0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, | 	0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, | ||||||
| 	0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, | 	0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, | ||||||
| 	0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, | 	0x35, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, | ||||||
| 	0x52, 0x0e, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, | 	0x52, 0x0e, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, | ||||||
| 	0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, | 	0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, | ||||||
| 	0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x3a, 0x0a, 0x0a, | 	0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x3a, 0x0a, 0x0a, | ||||||
| @@ -800,12 +800,12 @@ var file_sdk_database_newdbplugin_proto_database_proto_rawDesc = []byte{ | |||||||
| 	0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, | 	0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, | ||||||
| 	0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x65, 0x78, | 	0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x65, 0x78, | ||||||
| 	0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, | 	0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, | ||||||
| 	0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6e, | 	0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x64, | ||||||
| 	0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, | 	0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, | ||||||
| 	0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, | 	0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, | ||||||
| 	0x73, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x73, 0x74, | 	0x73, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x73, 0x74, | ||||||
| 	0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, | 	0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, | ||||||
| 	0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x53, 0x74, 0x61, | 	0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, 0x74, 0x61, | ||||||
| 	0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x12, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, | 	0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x12, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, | ||||||
| 	0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x50, 0x0a, 0x0e, 0x55, | 	0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x50, 0x0a, 0x0e, 0x55, | ||||||
| 	0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, | 	0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, | ||||||
| @@ -820,18 +820,18 @@ var file_sdk_database_newdbplugin_proto_database_proto_rawDesc = []byte{ | |||||||
| 	0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, | 	0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, | ||||||
| 	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, | 	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, | ||||||
| 	0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, | 	0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, | ||||||
| 	0x32, 0x1b, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, | 	0x32, 0x1b, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x43, | ||||||
| 	0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x08, 0x70, | 	0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x08, 0x70, | ||||||
| 	0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x3d, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, | 	0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x3d, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, | ||||||
| 	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6e, 0x65, | 	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x64, 0x62, | ||||||
| 	0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, | 	0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, | ||||||
| 	0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, | 	0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, | ||||||
| 	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x6c, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, | 	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x6c, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, | ||||||
| 	0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, | 	0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, | ||||||
| 	0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, | 	0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, | ||||||
| 	0x6e, 0x65, 0x77, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x37, 0x0a, 0x0a, 0x73, | 	0x6e, 0x65, 0x77, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x37, 0x0a, 0x0a, 0x73, | ||||||
| 	0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, | 	0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, | ||||||
| 	0x17, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x53, 0x74, | 	0x17, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, 0x74, | ||||||
| 	0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, | 	0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, | ||||||
| 	0x65, 0x6e, 0x74, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x10, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, | 	0x65, 0x6e, 0x74, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x10, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, | ||||||
| 	0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0e, 0x6e, 0x65, 0x77, | 	0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0e, 0x6e, 0x65, 0x77, | ||||||
| @@ -840,7 +840,7 @@ var file_sdk_database_newdbplugin_proto_database_proto_rawDesc = []byte{ | |||||||
| 	0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x6e, | 	0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x6e, | ||||||
| 	0x65, 0x77, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0a, | 	0x65, 0x77, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0a, | ||||||
| 	0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, | 	0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, | ||||||
| 	0x32, 0x17, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x53, | 	0x32, 0x17, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, | ||||||
| 	0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, | 	0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, | ||||||
| 	0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, | 	0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, | ||||||
| 	0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x68, 0x0a, 0x11, 0x44, | 	0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x68, 0x0a, 0x11, 0x44, | ||||||
| @@ -848,7 +848,7 @@ var file_sdk_database_newdbplugin_proto_database_proto_rawDesc = []byte{ | |||||||
| 	0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, | 	0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, | ||||||
| 	0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x0a, | 	0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x0a, | ||||||
| 	0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, | 	0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, | ||||||
| 	0x32, 0x17, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x53, | 	0x32, 0x17, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, | ||||||
| 	0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, | 	0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, | ||||||
| 	0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, | 	0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, | ||||||
| 	0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x0a, 0x0c, 0x54, | 	0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x0a, 0x0c, 0x54, | ||||||
| @@ -859,93 +859,93 @@ var file_sdk_database_newdbplugin_proto_database_proto_rawDesc = []byte{ | |||||||
| 	0x08, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, | 	0x08, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, | ||||||
| 	0x74, 0x79, 0x32, 0xa5, 0x03, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, | 	0x74, 0x79, 0x32, 0xa5, 0x03, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, | ||||||
| 	0x4d, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x1e, 0x2e, | 	0x4d, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x1e, 0x2e, | ||||||
| 	0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x49, 0x6e, 0x69, 0x74, | 	0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x49, 0x6e, 0x69, 0x74, | ||||||
| 	0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, | 	0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, | ||||||
| 	0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x49, 0x6e, 0x69, 0x74, | 	0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x49, 0x6e, 0x69, 0x74, | ||||||
| 	0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, | 	0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, | ||||||
| 	0x0a, 0x07, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x6e, 0x65, 0x77, 0x64, | 	0x0a, 0x07, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x64, 0x62, 0x70, 0x6c, | ||||||
| 	0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, | 	0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, | ||||||
| 	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, | 	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, | ||||||
| 	0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, | 	0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, | ||||||
| 	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, | 	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, | ||||||
| 	0x65, 0x72, 0x12, 0x1e, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, | 	0x65, 0x72, 0x12, 0x1e, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, | ||||||
| 	0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, | 	0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, | ||||||
| 	0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, | 	0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, | ||||||
| 	0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, | 	0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, | ||||||
| 	0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, | 	0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, | ||||||
| 	0x72, 0x12, 0x1e, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, | 	0x72, 0x12, 0x1e, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, | ||||||
| 	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, | 	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, | ||||||
| 	0x74, 0x1a, 0x1f, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, | 	0x74, 0x1a, 0x1f, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, | ||||||
| 	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, | 	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, | ||||||
| 	0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x2e, 0x6e, 0x65, 0x77, | 	0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x2e, 0x64, 0x62, 0x70, | ||||||
| 	0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, | 	0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, | ||||||
| 	0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x54, 0x79, 0x70, | 	0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x54, 0x79, 0x70, | ||||||
| 	0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x05, 0x43, 0x6c, 0x6f, | 	0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x05, 0x43, 0x6c, 0x6f, | ||||||
| 	0x73, 0x65, 0x12, 0x12, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, | 	0x73, 0x65, 0x12, 0x12, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, | ||||||
| 	0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, | 	0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, | ||||||
| 	0x75, 0x67, 0x69, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, | 	0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, | ||||||
| 	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, | 	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, | ||||||
| 	0x72, 0x70, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x64, 0x61, 0x74, | 	0x72, 0x70, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x64, 0x61, 0x74, | ||||||
| 	0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, | 	0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x76, | ||||||
| 	0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, | 	0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
| 	file_sdk_database_newdbplugin_proto_database_proto_rawDescOnce sync.Once | 	file_sdk_database_dbplugin_v5_proto_database_proto_rawDescOnce sync.Once | ||||||
| 	file_sdk_database_newdbplugin_proto_database_proto_rawDescData = file_sdk_database_newdbplugin_proto_database_proto_rawDesc | 	file_sdk_database_dbplugin_v5_proto_database_proto_rawDescData = file_sdk_database_dbplugin_v5_proto_database_proto_rawDesc | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP() []byte { | func file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP() []byte { | ||||||
| 	file_sdk_database_newdbplugin_proto_database_proto_rawDescOnce.Do(func() { | 	file_sdk_database_dbplugin_v5_proto_database_proto_rawDescOnce.Do(func() { | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_rawDescData = protoimpl.X.CompressGZIP(file_sdk_database_newdbplugin_proto_database_proto_rawDescData) | 		file_sdk_database_dbplugin_v5_proto_database_proto_rawDescData = protoimpl.X.CompressGZIP(file_sdk_database_dbplugin_v5_proto_database_proto_rawDescData) | ||||||
| 	}) | 	}) | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescData | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescData | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var file_sdk_database_newdbplugin_proto_database_proto_msgTypes = make([]protoimpl.MessageInfo, 14) | var file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes = make([]protoimpl.MessageInfo, 14) | ||||||
| var file_sdk_database_newdbplugin_proto_database_proto_goTypes = []interface{}{ | var file_sdk_database_dbplugin_v5_proto_database_proto_goTypes = []interface{}{ | ||||||
| 	(*InitializeRequest)(nil),   // 0: newdbplugin.InitializeRequest | 	(*InitializeRequest)(nil),   // 0: dbplugin.v5.InitializeRequest | ||||||
| 	(*InitializeResponse)(nil),  // 1: newdbplugin.InitializeResponse | 	(*InitializeResponse)(nil),  // 1: dbplugin.v5.InitializeResponse | ||||||
| 	(*NewUserRequest)(nil),      // 2: newdbplugin.NewUserRequest | 	(*NewUserRequest)(nil),      // 2: dbplugin.v5.NewUserRequest | ||||||
| 	(*UsernameConfig)(nil),      // 3: newdbplugin.UsernameConfig | 	(*UsernameConfig)(nil),      // 3: dbplugin.v5.UsernameConfig | ||||||
| 	(*NewUserResponse)(nil),     // 4: newdbplugin.NewUserResponse | 	(*NewUserResponse)(nil),     // 4: dbplugin.v5.NewUserResponse | ||||||
| 	(*UpdateUserRequest)(nil),   // 5: newdbplugin.UpdateUserRequest | 	(*UpdateUserRequest)(nil),   // 5: dbplugin.v5.UpdateUserRequest | ||||||
| 	(*ChangePassword)(nil),      // 6: newdbplugin.ChangePassword | 	(*ChangePassword)(nil),      // 6: dbplugin.v5.ChangePassword | ||||||
| 	(*ChangeExpiration)(nil),    // 7: newdbplugin.ChangeExpiration | 	(*ChangeExpiration)(nil),    // 7: dbplugin.v5.ChangeExpiration | ||||||
| 	(*UpdateUserResponse)(nil),  // 8: newdbplugin.UpdateUserResponse | 	(*UpdateUserResponse)(nil),  // 8: dbplugin.v5.UpdateUserResponse | ||||||
| 	(*DeleteUserRequest)(nil),   // 9: newdbplugin.DeleteUserRequest | 	(*DeleteUserRequest)(nil),   // 9: dbplugin.v5.DeleteUserRequest | ||||||
| 	(*DeleteUserResponse)(nil),  // 10: newdbplugin.DeleteUserResponse | 	(*DeleteUserResponse)(nil),  // 10: dbplugin.v5.DeleteUserResponse | ||||||
| 	(*TypeResponse)(nil),        // 11: newdbplugin.TypeResponse | 	(*TypeResponse)(nil),        // 11: dbplugin.v5.TypeResponse | ||||||
| 	(*Statements)(nil),          // 12: newdbplugin.Statements | 	(*Statements)(nil),          // 12: dbplugin.v5.Statements | ||||||
| 	(*Empty)(nil),               // 13: newdbplugin.Empty | 	(*Empty)(nil),               // 13: dbplugin.v5.Empty | ||||||
| 	(*_struct.Struct)(nil),      // 14: google.protobuf.Struct | 	(*_struct.Struct)(nil),      // 14: google.protobuf.Struct | ||||||
| 	(*timestamp.Timestamp)(nil), // 15: google.protobuf.Timestamp | 	(*timestamp.Timestamp)(nil), // 15: google.protobuf.Timestamp | ||||||
| } | } | ||||||
| var file_sdk_database_newdbplugin_proto_database_proto_depIdxs = []int32{ | var file_sdk_database_dbplugin_v5_proto_database_proto_depIdxs = []int32{ | ||||||
| 	14, // 0: newdbplugin.InitializeRequest.config_data:type_name -> google.protobuf.Struct | 	14, // 0: dbplugin.v5.InitializeRequest.config_data:type_name -> google.protobuf.Struct | ||||||
| 	14, // 1: newdbplugin.InitializeResponse.config_data:type_name -> google.protobuf.Struct | 	14, // 1: dbplugin.v5.InitializeResponse.config_data:type_name -> google.protobuf.Struct | ||||||
| 	3,  // 2: newdbplugin.NewUserRequest.username_config:type_name -> newdbplugin.UsernameConfig | 	3,  // 2: dbplugin.v5.NewUserRequest.username_config:type_name -> dbplugin.v5.UsernameConfig | ||||||
| 	15, // 3: newdbplugin.NewUserRequest.expiration:type_name -> google.protobuf.Timestamp | 	15, // 3: dbplugin.v5.NewUserRequest.expiration:type_name -> google.protobuf.Timestamp | ||||||
| 	12, // 4: newdbplugin.NewUserRequest.statements:type_name -> newdbplugin.Statements | 	12, // 4: dbplugin.v5.NewUserRequest.statements:type_name -> dbplugin.v5.Statements | ||||||
| 	12, // 5: newdbplugin.NewUserRequest.rollback_statements:type_name -> newdbplugin.Statements | 	12, // 5: dbplugin.v5.NewUserRequest.rollback_statements:type_name -> dbplugin.v5.Statements | ||||||
| 	6,  // 6: newdbplugin.UpdateUserRequest.password:type_name -> newdbplugin.ChangePassword | 	6,  // 6: dbplugin.v5.UpdateUserRequest.password:type_name -> dbplugin.v5.ChangePassword | ||||||
| 	7,  // 7: newdbplugin.UpdateUserRequest.expiration:type_name -> newdbplugin.ChangeExpiration | 	7,  // 7: dbplugin.v5.UpdateUserRequest.expiration:type_name -> dbplugin.v5.ChangeExpiration | ||||||
| 	12, // 8: newdbplugin.ChangePassword.statements:type_name -> newdbplugin.Statements | 	12, // 8: dbplugin.v5.ChangePassword.statements:type_name -> dbplugin.v5.Statements | ||||||
| 	15, // 9: newdbplugin.ChangeExpiration.new_expiration:type_name -> google.protobuf.Timestamp | 	15, // 9: dbplugin.v5.ChangeExpiration.new_expiration:type_name -> google.protobuf.Timestamp | ||||||
| 	12, // 10: newdbplugin.ChangeExpiration.statements:type_name -> newdbplugin.Statements | 	12, // 10: dbplugin.v5.ChangeExpiration.statements:type_name -> dbplugin.v5.Statements | ||||||
| 	12, // 11: newdbplugin.DeleteUserRequest.statements:type_name -> newdbplugin.Statements | 	12, // 11: dbplugin.v5.DeleteUserRequest.statements:type_name -> dbplugin.v5.Statements | ||||||
| 	0,  // 12: newdbplugin.Database.Initialize:input_type -> newdbplugin.InitializeRequest | 	0,  // 12: dbplugin.v5.Database.Initialize:input_type -> dbplugin.v5.InitializeRequest | ||||||
| 	2,  // 13: newdbplugin.Database.NewUser:input_type -> newdbplugin.NewUserRequest | 	2,  // 13: dbplugin.v5.Database.NewUser:input_type -> dbplugin.v5.NewUserRequest | ||||||
| 	5,  // 14: newdbplugin.Database.UpdateUser:input_type -> newdbplugin.UpdateUserRequest | 	5,  // 14: dbplugin.v5.Database.UpdateUser:input_type -> dbplugin.v5.UpdateUserRequest | ||||||
| 	9,  // 15: newdbplugin.Database.DeleteUser:input_type -> newdbplugin.DeleteUserRequest | 	9,  // 15: dbplugin.v5.Database.DeleteUser:input_type -> dbplugin.v5.DeleteUserRequest | ||||||
| 	13, // 16: newdbplugin.Database.Type:input_type -> newdbplugin.Empty | 	13, // 16: dbplugin.v5.Database.Type:input_type -> dbplugin.v5.Empty | ||||||
| 	13, // 17: newdbplugin.Database.Close:input_type -> newdbplugin.Empty | 	13, // 17: dbplugin.v5.Database.Close:input_type -> dbplugin.v5.Empty | ||||||
| 	1,  // 18: newdbplugin.Database.Initialize:output_type -> newdbplugin.InitializeResponse | 	1,  // 18: dbplugin.v5.Database.Initialize:output_type -> dbplugin.v5.InitializeResponse | ||||||
| 	4,  // 19: newdbplugin.Database.NewUser:output_type -> newdbplugin.NewUserResponse | 	4,  // 19: dbplugin.v5.Database.NewUser:output_type -> dbplugin.v5.NewUserResponse | ||||||
| 	8,  // 20: newdbplugin.Database.UpdateUser:output_type -> newdbplugin.UpdateUserResponse | 	8,  // 20: dbplugin.v5.Database.UpdateUser:output_type -> dbplugin.v5.UpdateUserResponse | ||||||
| 	10, // 21: newdbplugin.Database.DeleteUser:output_type -> newdbplugin.DeleteUserResponse | 	10, // 21: dbplugin.v5.Database.DeleteUser:output_type -> dbplugin.v5.DeleteUserResponse | ||||||
| 	11, // 22: newdbplugin.Database.Type:output_type -> newdbplugin.TypeResponse | 	11, // 22: dbplugin.v5.Database.Type:output_type -> dbplugin.v5.TypeResponse | ||||||
| 	13, // 23: newdbplugin.Database.Close:output_type -> newdbplugin.Empty | 	13, // 23: dbplugin.v5.Database.Close:output_type -> dbplugin.v5.Empty | ||||||
| 	18, // [18:24] is the sub-list for method output_type | 	18, // [18:24] is the sub-list for method output_type | ||||||
| 	12, // [12:18] is the sub-list for method input_type | 	12, // [12:18] is the sub-list for method input_type | ||||||
| 	12, // [12:12] is the sub-list for extension type_name | 	12, // [12:12] is the sub-list for extension type_name | ||||||
| @@ -953,13 +953,13 @@ var file_sdk_database_newdbplugin_proto_database_proto_depIdxs = []int32{ | |||||||
| 	0,  // [0:12] is the sub-list for field type_name | 	0,  // [0:12] is the sub-list for field type_name | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func init() { file_sdk_database_newdbplugin_proto_database_proto_init() } | func init() { file_sdk_database_dbplugin_v5_proto_database_proto_init() } | ||||||
| func file_sdk_database_newdbplugin_proto_database_proto_init() { | func file_sdk_database_dbplugin_v5_proto_database_proto_init() { | ||||||
| 	if File_sdk_database_newdbplugin_proto_database_proto != nil { | 	if File_sdk_database_dbplugin_v5_proto_database_proto != nil { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if !protoimpl.UnsafeEnabled { | 	if !protoimpl.UnsafeEnabled { | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*InitializeRequest); i { | 			switch v := v.(*InitializeRequest); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -971,7 +971,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*InitializeResponse); i { | 			switch v := v.(*InitializeResponse); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -983,7 +983,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*NewUserRequest); i { | 			switch v := v.(*NewUserRequest); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -995,7 +995,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*UsernameConfig); i { | 			switch v := v.(*UsernameConfig); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1007,7 +1007,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*NewUserResponse); i { | 			switch v := v.(*NewUserResponse); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1019,7 +1019,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*UpdateUserRequest); i { | 			switch v := v.(*UpdateUserRequest); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1031,7 +1031,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*ChangePassword); i { | 			switch v := v.(*ChangePassword); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1043,7 +1043,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*ChangeExpiration); i { | 			switch v := v.(*ChangeExpiration); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1055,7 +1055,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*UpdateUserResponse); i { | 			switch v := v.(*UpdateUserResponse); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1067,7 +1067,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*DeleteUserRequest); i { | 			switch v := v.(*DeleteUserRequest); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1079,7 +1079,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*DeleteUserResponse); i { | 			switch v := v.(*DeleteUserResponse); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1091,7 +1091,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*TypeResponse); i { | 			switch v := v.(*TypeResponse); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1103,7 +1103,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*Statements); i { | 			switch v := v.(*Statements); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1115,7 +1115,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*Empty); i { | 			switch v := v.(*Empty); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1132,20 +1132,20 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 	out := protoimpl.TypeBuilder{ | 	out := protoimpl.TypeBuilder{ | ||||||
| 		File: protoimpl.DescBuilder{ | 		File: protoimpl.DescBuilder{ | ||||||
| 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(), | 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(), | ||||||
| 			RawDescriptor: file_sdk_database_newdbplugin_proto_database_proto_rawDesc, | 			RawDescriptor: file_sdk_database_dbplugin_v5_proto_database_proto_rawDesc, | ||||||
| 			NumEnums:      0, | 			NumEnums:      0, | ||||||
| 			NumMessages:   14, | 			NumMessages:   14, | ||||||
| 			NumExtensions: 0, | 			NumExtensions: 0, | ||||||
| 			NumServices:   1, | 			NumServices:   1, | ||||||
| 		}, | 		}, | ||||||
| 		GoTypes:           file_sdk_database_newdbplugin_proto_database_proto_goTypes, | 		GoTypes:           file_sdk_database_dbplugin_v5_proto_database_proto_goTypes, | ||||||
| 		DependencyIndexes: file_sdk_database_newdbplugin_proto_database_proto_depIdxs, | 		DependencyIndexes: file_sdk_database_dbplugin_v5_proto_database_proto_depIdxs, | ||||||
| 		MessageInfos:      file_sdk_database_newdbplugin_proto_database_proto_msgTypes, | 		MessageInfos:      file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes, | ||||||
| 	}.Build() | 	}.Build() | ||||||
| 	File_sdk_database_newdbplugin_proto_database_proto = out.File | 	File_sdk_database_dbplugin_v5_proto_database_proto = out.File | ||||||
| 	file_sdk_database_newdbplugin_proto_database_proto_rawDesc = nil | 	file_sdk_database_dbplugin_v5_proto_database_proto_rawDesc = nil | ||||||
| 	file_sdk_database_newdbplugin_proto_database_proto_goTypes = nil | 	file_sdk_database_dbplugin_v5_proto_database_proto_goTypes = nil | ||||||
| 	file_sdk_database_newdbplugin_proto_database_proto_depIdxs = nil | 	file_sdk_database_dbplugin_v5_proto_database_proto_depIdxs = nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Reference imports to suppress errors if they are not otherwise used. | // Reference imports to suppress errors if they are not otherwise used. | ||||||
| @@ -1178,7 +1178,7 @@ func NewDatabaseClient(cc grpc.ClientConnInterface) DatabaseClient { | |||||||
| 
 | 
 | ||||||
| func (c *databaseClient) Initialize(ctx context.Context, in *InitializeRequest, opts ...grpc.CallOption) (*InitializeResponse, error) { | func (c *databaseClient) Initialize(ctx context.Context, in *InitializeRequest, opts ...grpc.CallOption) (*InitializeResponse, error) { | ||||||
| 	out := new(InitializeResponse) | 	out := new(InitializeResponse) | ||||||
| 	err := c.cc.Invoke(ctx, "/newdbplugin.Database/Initialize", in, out, opts...) | 	err := c.cc.Invoke(ctx, "/dbplugin.v5.Database/Initialize", in, out, opts...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -1187,7 +1187,7 @@ func (c *databaseClient) Initialize(ctx context.Context, in *InitializeRequest, | |||||||
| 
 | 
 | ||||||
| func (c *databaseClient) NewUser(ctx context.Context, in *NewUserRequest, opts ...grpc.CallOption) (*NewUserResponse, error) { | func (c *databaseClient) NewUser(ctx context.Context, in *NewUserRequest, opts ...grpc.CallOption) (*NewUserResponse, error) { | ||||||
| 	out := new(NewUserResponse) | 	out := new(NewUserResponse) | ||||||
| 	err := c.cc.Invoke(ctx, "/newdbplugin.Database/NewUser", in, out, opts...) | 	err := c.cc.Invoke(ctx, "/dbplugin.v5.Database/NewUser", in, out, opts...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -1196,7 +1196,7 @@ func (c *databaseClient) NewUser(ctx context.Context, in *NewUserRequest, opts . | |||||||
| 
 | 
 | ||||||
| func (c *databaseClient) UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*UpdateUserResponse, error) { | func (c *databaseClient) UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*UpdateUserResponse, error) { | ||||||
| 	out := new(UpdateUserResponse) | 	out := new(UpdateUserResponse) | ||||||
| 	err := c.cc.Invoke(ctx, "/newdbplugin.Database/UpdateUser", in, out, opts...) | 	err := c.cc.Invoke(ctx, "/dbplugin.v5.Database/UpdateUser", in, out, opts...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -1205,7 +1205,7 @@ func (c *databaseClient) UpdateUser(ctx context.Context, in *UpdateUserRequest, | |||||||
| 
 | 
 | ||||||
| func (c *databaseClient) DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*DeleteUserResponse, error) { | func (c *databaseClient) DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*DeleteUserResponse, error) { | ||||||
| 	out := new(DeleteUserResponse) | 	out := new(DeleteUserResponse) | ||||||
| 	err := c.cc.Invoke(ctx, "/newdbplugin.Database/DeleteUser", in, out, opts...) | 	err := c.cc.Invoke(ctx, "/dbplugin.v5.Database/DeleteUser", in, out, opts...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -1214,7 +1214,7 @@ func (c *databaseClient) DeleteUser(ctx context.Context, in *DeleteUserRequest, | |||||||
| 
 | 
 | ||||||
| func (c *databaseClient) Type(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TypeResponse, error) { | func (c *databaseClient) Type(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TypeResponse, error) { | ||||||
| 	out := new(TypeResponse) | 	out := new(TypeResponse) | ||||||
| 	err := c.cc.Invoke(ctx, "/newdbplugin.Database/Type", in, out, opts...) | 	err := c.cc.Invoke(ctx, "/dbplugin.v5.Database/Type", in, out, opts...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -1223,7 +1223,7 @@ func (c *databaseClient) Type(ctx context.Context, in *Empty, opts ...grpc.CallO | |||||||
| 
 | 
 | ||||||
| func (c *databaseClient) Close(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { | func (c *databaseClient) Close(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { | ||||||
| 	out := new(Empty) | 	out := new(Empty) | ||||||
| 	err := c.cc.Invoke(ctx, "/newdbplugin.Database/Close", in, out, opts...) | 	err := c.cc.Invoke(ctx, "/dbplugin.v5.Database/Close", in, out, opts...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -1277,7 +1277,7 @@ func _Database_Initialize_Handler(srv interface{}, ctx context.Context, dec func | |||||||
| 	} | 	} | ||||||
| 	info := &grpc.UnaryServerInfo{ | 	info := &grpc.UnaryServerInfo{ | ||||||
| 		Server:     srv, | 		Server:     srv, | ||||||
| 		FullMethod: "/newdbplugin.Database/Initialize", | 		FullMethod: "/dbplugin.v5.Database/Initialize", | ||||||
| 	} | 	} | ||||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||||
| 		return srv.(DatabaseServer).Initialize(ctx, req.(*InitializeRequest)) | 		return srv.(DatabaseServer).Initialize(ctx, req.(*InitializeRequest)) | ||||||
| @@ -1295,7 +1295,7 @@ func _Database_NewUser_Handler(srv interface{}, ctx context.Context, dec func(in | |||||||
| 	} | 	} | ||||||
| 	info := &grpc.UnaryServerInfo{ | 	info := &grpc.UnaryServerInfo{ | ||||||
| 		Server:     srv, | 		Server:     srv, | ||||||
| 		FullMethod: "/newdbplugin.Database/NewUser", | 		FullMethod: "/dbplugin.v5.Database/NewUser", | ||||||
| 	} | 	} | ||||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||||
| 		return srv.(DatabaseServer).NewUser(ctx, req.(*NewUserRequest)) | 		return srv.(DatabaseServer).NewUser(ctx, req.(*NewUserRequest)) | ||||||
| @@ -1313,7 +1313,7 @@ func _Database_UpdateUser_Handler(srv interface{}, ctx context.Context, dec func | |||||||
| 	} | 	} | ||||||
| 	info := &grpc.UnaryServerInfo{ | 	info := &grpc.UnaryServerInfo{ | ||||||
| 		Server:     srv, | 		Server:     srv, | ||||||
| 		FullMethod: "/newdbplugin.Database/UpdateUser", | 		FullMethod: "/dbplugin.v5.Database/UpdateUser", | ||||||
| 	} | 	} | ||||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||||
| 		return srv.(DatabaseServer).UpdateUser(ctx, req.(*UpdateUserRequest)) | 		return srv.(DatabaseServer).UpdateUser(ctx, req.(*UpdateUserRequest)) | ||||||
| @@ -1331,7 +1331,7 @@ func _Database_DeleteUser_Handler(srv interface{}, ctx context.Context, dec func | |||||||
| 	} | 	} | ||||||
| 	info := &grpc.UnaryServerInfo{ | 	info := &grpc.UnaryServerInfo{ | ||||||
| 		Server:     srv, | 		Server:     srv, | ||||||
| 		FullMethod: "/newdbplugin.Database/DeleteUser", | 		FullMethod: "/dbplugin.v5.Database/DeleteUser", | ||||||
| 	} | 	} | ||||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||||
| 		return srv.(DatabaseServer).DeleteUser(ctx, req.(*DeleteUserRequest)) | 		return srv.(DatabaseServer).DeleteUser(ctx, req.(*DeleteUserRequest)) | ||||||
| @@ -1349,7 +1349,7 @@ func _Database_Type_Handler(srv interface{}, ctx context.Context, dec func(inter | |||||||
| 	} | 	} | ||||||
| 	info := &grpc.UnaryServerInfo{ | 	info := &grpc.UnaryServerInfo{ | ||||||
| 		Server:     srv, | 		Server:     srv, | ||||||
| 		FullMethod: "/newdbplugin.Database/Type", | 		FullMethod: "/dbplugin.v5.Database/Type", | ||||||
| 	} | 	} | ||||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||||
| 		return srv.(DatabaseServer).Type(ctx, req.(*Empty)) | 		return srv.(DatabaseServer).Type(ctx, req.(*Empty)) | ||||||
| @@ -1367,7 +1367,7 @@ func _Database_Close_Handler(srv interface{}, ctx context.Context, dec func(inte | |||||||
| 	} | 	} | ||||||
| 	info := &grpc.UnaryServerInfo{ | 	info := &grpc.UnaryServerInfo{ | ||||||
| 		Server:     srv, | 		Server:     srv, | ||||||
| 		FullMethod: "/newdbplugin.Database/Close", | 		FullMethod: "/dbplugin.v5.Database/Close", | ||||||
| 	} | 	} | ||||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||||
| 		return srv.(DatabaseServer).Close(ctx, req.(*Empty)) | 		return srv.(DatabaseServer).Close(ctx, req.(*Empty)) | ||||||
| @@ -1376,7 +1376,7 @@ func _Database_Close_Handler(srv interface{}, ctx context.Context, dec func(inte | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var _Database_serviceDesc = grpc.ServiceDesc{ | var _Database_serviceDesc = grpc.ServiceDesc{ | ||||||
| 	ServiceName: "newdbplugin.Database", | 	ServiceName: "dbplugin.v5.Database", | ||||||
| 	HandlerType: (*DatabaseServer)(nil), | 	HandlerType: (*DatabaseServer)(nil), | ||||||
| 	Methods: []grpc.MethodDesc{ | 	Methods: []grpc.MethodDesc{ | ||||||
| 		{ | 		{ | ||||||
| @@ -1405,5 +1405,5 @@ var _Database_serviceDesc = grpc.ServiceDesc{ | |||||||
| 		}, | 		}, | ||||||
| 	}, | 	}, | ||||||
| 	Streams:  []grpc.StreamDesc{}, | 	Streams:  []grpc.StreamDesc{}, | ||||||
| 	Metadata: "sdk/database/newdbplugin/proto/database.proto", | 	Metadata: "sdk/database/dbplugin/v5/proto/database.proto", | ||||||
| } | } | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| syntax = "proto3"; | syntax = "proto3"; | ||||||
| package newdbplugin; // TODO: Update name | package dbplugin.v5; | ||||||
| 
 | 
 | ||||||
| option go_package = "github.com/hashicorp/vault/sdk/database/newdbplugin/proto"; | option go_package = "github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto"; | ||||||
| 
 | 
 | ||||||
| import "google/protobuf/struct.proto"; | import "google/protobuf/struct.proto"; | ||||||
| import "google/protobuf/timestamp.proto"; | import "google/protobuf/timestamp.proto"; | ||||||
| @@ -6,7 +6,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func getRequestTimeout(t *testing.T) time.Duration { | func getRequestTimeout(t *testing.T) time.Duration { | ||||||
| @@ -22,7 +22,7 @@ func getRequestTimeout(t *testing.T) time.Duration { | |||||||
| 	return dur | 	return dur | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func AssertInitialize(t *testing.T, db newdbplugin.Database, req newdbplugin.InitializeRequest) newdbplugin.InitializeResponse { | func AssertInitialize(t *testing.T, db dbplugin.Database, req dbplugin.InitializeRequest) dbplugin.InitializeResponse { | ||||||
| 	t.Helper() | 	t.Helper() | ||||||
| 
 | 
 | ||||||
| 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | ||||||
| @@ -35,7 +35,7 @@ func AssertInitialize(t *testing.T, db newdbplugin.Database, req newdbplugin.Ini | |||||||
| 	return resp | 	return resp | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func AssertNewUser(t *testing.T, db newdbplugin.Database, req newdbplugin.NewUserRequest) newdbplugin.NewUserResponse { | func AssertNewUser(t *testing.T, db dbplugin.Database, req dbplugin.NewUserRequest) dbplugin.NewUserResponse { | ||||||
| 	t.Helper() | 	t.Helper() | ||||||
| 
 | 
 | ||||||
| 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | ||||||
| @@ -52,7 +52,7 @@ func AssertNewUser(t *testing.T, db newdbplugin.Database, req newdbplugin.NewUse | |||||||
| 	return resp | 	return resp | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func AssertUpdateUser(t *testing.T, db newdbplugin.Database, req newdbplugin.UpdateUserRequest) { | func AssertUpdateUser(t *testing.T, db dbplugin.Database, req dbplugin.UpdateUserRequest) { | ||||||
| 	t.Helper() | 	t.Helper() | ||||||
| 
 | 
 | ||||||
| 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | ||||||
| @@ -64,7 +64,7 @@ func AssertUpdateUser(t *testing.T, db newdbplugin.Database, req newdbplugin.Upd | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func AssertDeleteUser(t *testing.T, db newdbplugin.Database, req newdbplugin.DeleteUserRequest) { | func AssertDeleteUser(t *testing.T, db dbplugin.Database, req dbplugin.DeleteUserRequest) { | ||||||
| 	t.Helper() | 	t.Helper() | ||||||
| 
 | 
 | ||||||
| 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | ||||||
| @@ -76,7 +76,7 @@ func AssertDeleteUser(t *testing.T, db newdbplugin.Database, req newdbplugin.Del | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func AssertClose(t *testing.T, db newdbplugin.Database) { | func AssertClose(t *testing.T, db dbplugin.Database) { | ||||||
| 	t.Helper() | 	t.Helper() | ||||||
| 	err := db.Close() | 	err := db.Close() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -8,7 +8,7 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
| 	"unicode" | 	"unicode" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin/proto" | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
|  |  | ||||||
| 	"google.golang.org/protobuf/types/known/structpb" | 	"google.golang.org/protobuf/types/known/structpb" | ||||||
| 	"google.golang.org/protobuf/types/known/timestamppb" | 	"google.golang.org/protobuf/types/known/timestamppb" | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/golang/protobuf/ptypes" | 	"github.com/golang/protobuf/ptypes" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin/proto" | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/pluginutil" | 	"github.com/hashicorp/vault/sdk/helper/pluginutil" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin/proto" | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
| 	"google.golang.org/grpc" | 	"google.golang.org/grpc" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/go-plugin" | 	"github.com/hashicorp/go-plugin" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin/proto" | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
| 	"google.golang.org/grpc" | 	"google.golang.org/grpc" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/golang/protobuf/ptypes" | 	"github.com/golang/protobuf/ptypes" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin/proto" | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
| 	"google.golang.org/grpc/codes" | 	"google.golang.org/grpc/codes" | ||||||
| 	"google.golang.org/grpc/status" | 	"google.golang.org/grpc/status" | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/golang/protobuf/ptypes" | 	"github.com/golang/protobuf/ptypes" | ||||||
| 	"github.com/golang/protobuf/ptypes/timestamp" | 	"github.com/golang/protobuf/ptypes/timestamp" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin/proto" | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
| 	"google.golang.org/grpc/codes" | 	"google.golang.org/grpc/codes" | ||||||
| 	"google.golang.org/grpc/status" | 	"google.golang.org/grpc/status" | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func getRequestTimeout(t *testing.T) time.Duration { | func getRequestTimeout(t *testing.T) time.Duration { | ||||||
| @@ -22,7 +22,7 @@ func getRequestTimeout(t *testing.T) time.Duration { | |||||||
| 	return dur | 	return dur | ||||||
| } | } | ||||||
|  |  | ||||||
| func AssertInitialize(t *testing.T, db newdbplugin.Database, req newdbplugin.InitializeRequest) newdbplugin.InitializeResponse { | func AssertInitialize(t *testing.T, db dbplugin.Database, req dbplugin.InitializeRequest) dbplugin.InitializeResponse { | ||||||
| 	t.Helper() | 	t.Helper() | ||||||
|  |  | ||||||
| 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | ||||||
| @@ -35,7 +35,7 @@ func AssertInitialize(t *testing.T, db newdbplugin.Database, req newdbplugin.Ini | |||||||
| 	return resp | 	return resp | ||||||
| } | } | ||||||
|  |  | ||||||
| func AssertNewUser(t *testing.T, db newdbplugin.Database, req newdbplugin.NewUserRequest) newdbplugin.NewUserResponse { | func AssertNewUser(t *testing.T, db dbplugin.Database, req dbplugin.NewUserRequest) dbplugin.NewUserResponse { | ||||||
| 	t.Helper() | 	t.Helper() | ||||||
|  |  | ||||||
| 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | ||||||
| @@ -52,7 +52,7 @@ func AssertNewUser(t *testing.T, db newdbplugin.Database, req newdbplugin.NewUse | |||||||
| 	return resp | 	return resp | ||||||
| } | } | ||||||
|  |  | ||||||
| func AssertUpdateUser(t *testing.T, db newdbplugin.Database, req newdbplugin.UpdateUserRequest) { | func AssertUpdateUser(t *testing.T, db dbplugin.Database, req dbplugin.UpdateUserRequest) { | ||||||
| 	t.Helper() | 	t.Helper() | ||||||
|  |  | ||||||
| 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | ||||||
| @@ -64,7 +64,7 @@ func AssertUpdateUser(t *testing.T, db newdbplugin.Database, req newdbplugin.Upd | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func AssertDeleteUser(t *testing.T, db newdbplugin.Database, req newdbplugin.DeleteUserRequest) { | func AssertDeleteUser(t *testing.T, db dbplugin.Database, req dbplugin.DeleteUserRequest) { | ||||||
| 	t.Helper() | 	t.Helper() | ||||||
|  |  | ||||||
| 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | ||||||
| @@ -76,7 +76,7 @@ func AssertDeleteUser(t *testing.T, db newdbplugin.Database, req newdbplugin.Del | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func AssertClose(t *testing.T, db newdbplugin.Database) { | func AssertClose(t *testing.T, db dbplugin.Database) { | ||||||
| 	t.Helper() | 	t.Helper() | ||||||
| 	err := db.Close() | 	err := db.Close() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|   | |||||||
| @@ -13,8 +13,8 @@ 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/sdk/database/dbplugin" | 	v4 "github.com/hashicorp/vault/sdk/database/dbplugin" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin" | 	v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
| 	"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" | ||||||
| @@ -109,7 +109,7 @@ func (c *PluginCatalog) getPluginTypeFromUnknown(ctx context.Context, logger log | |||||||
| func isDatabasePlugin(ctx context.Context, plugin *pluginutil.PluginRunner) error { | func isDatabasePlugin(ctx context.Context, plugin *pluginutil.PluginRunner) error { | ||||||
| 	merr := &multierror.Error{} | 	merr := &multierror.Error{} | ||||||
| 	// Attempt to run as database V5 plugin | 	// Attempt to run as database V5 plugin | ||||||
| 	v5Client, err := newdbplugin.NewPluginClient(ctx, nil, plugin, log.NewNullLogger(), true) | 	v5Client, err := v5.NewPluginClient(ctx, nil, plugin, log.NewNullLogger(), true) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		// Close the client and cleanup the plugin process | 		// Close the client and cleanup the plugin process | ||||||
| 		v5Client.Close() | 		v5Client.Close() | ||||||
| @@ -117,7 +117,7 @@ func isDatabasePlugin(ctx context.Context, plugin *pluginutil.PluginRunner) erro | |||||||
| 	} | 	} | ||||||
| 	merr = multierror.Append(merr, fmt.Errorf("failed to load plugin as database v5: %w", err)) | 	merr = multierror.Append(merr, fmt.Errorf("failed to load plugin as database v5: %w", err)) | ||||||
|  |  | ||||||
| 	v4Client, err := dbplugin.NewPluginClient(ctx, nil, plugin, log.NewNullLogger(), true) | 	v4Client, err := v4.NewPluginClient(ctx, nil, plugin, log.NewNullLogger(), true) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		// Close the client and cleanup the plugin process | 		// Close the client and cleanup the plugin process | ||||||
| 		v4Client.Close() | 		v4Client.Close() | ||||||
|   | |||||||
							
								
								
									
										178
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/database.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/database.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,178 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Database to manipulate users within an external system (typically a database). | ||||||
|  | type Database interface { | ||||||
|  | 	// Initialize the database plugin. This is the equivalent of a constructor for the | ||||||
|  | 	// database object itself. | ||||||
|  | 	Initialize(ctx context.Context, req InitializeRequest) (InitializeResponse, error) | ||||||
|  |  | ||||||
|  | 	// NewUser creates a new user within the database. This user is temporary in that it | ||||||
|  | 	// will exist until the TTL expires. | ||||||
|  | 	NewUser(ctx context.Context, req NewUserRequest) (NewUserResponse, error) | ||||||
|  |  | ||||||
|  | 	// UpdateUser updates an existing user within the database. | ||||||
|  | 	UpdateUser(ctx context.Context, req UpdateUserRequest) (UpdateUserResponse, error) | ||||||
|  |  | ||||||
|  | 	// DeleteUser from the database. This should not error if the user didn't | ||||||
|  | 	// exist prior to this call. | ||||||
|  | 	DeleteUser(ctx context.Context, req DeleteUserRequest) (DeleteUserResponse, error) | ||||||
|  |  | ||||||
|  | 	// Type returns the Name 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. This is used | ||||||
|  | 	// for things like metrics and logging. No behavior is switched on this. | ||||||
|  | 	Type() (string, error) | ||||||
|  |  | ||||||
|  | 	// Close attempts to close the underlying database connection that was | ||||||
|  | 	// established by the backend. | ||||||
|  | 	Close() error | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // /////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Database Request & Response Objects | ||||||
|  | // These request and response objects are *not* protobuf types because gRPC does not | ||||||
|  | // support all types that we need in a nice way. For instance, gRPC does not support | ||||||
|  | // map[string]interface{}. It does have an `Any` type, but converting it to a map | ||||||
|  | // requires extensive use of reflection and knowing what types to support ahead of | ||||||
|  | // time. Instead these types are made as user-friendly as possible so the conversion | ||||||
|  | // between protobuf types and request/response objects is handled by Vault developers | ||||||
|  | // rather than needing to be handled by external plugin developers. | ||||||
|  | // /////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  | // Initialize() | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | // InitializeRequest contains all information needed to initialize a database plugin. | ||||||
|  | type InitializeRequest struct { | ||||||
|  | 	// Config to initialize the database with. This can include things like connection details, | ||||||
|  | 	// a "root" username & password, etc. This will not include all configuration items specified | ||||||
|  | 	// when configuring the database. Some values will be stripped out by the database engine | ||||||
|  | 	// prior to being passed to the plugin. | ||||||
|  | 	Config map[string]interface{} | ||||||
|  |  | ||||||
|  | 	// VerifyConnection during initialization. If true, a connection should be made to the | ||||||
|  | 	// database to verify the connection can be made. If false, no connection should be made | ||||||
|  | 	// on initialization. | ||||||
|  | 	VerifyConnection bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // InitializeResponse returns any information Vault needs to know after initializing | ||||||
|  | // a database plugin. | ||||||
|  | type InitializeResponse struct { | ||||||
|  | 	// Config that should be saved in Vault. This may differ from the config in the request, | ||||||
|  | 	// but should contain everything required to Initialize the database. | ||||||
|  | 	// REQUIRED in order to save the configuration into Vault after initialization | ||||||
|  | 	Config map[string]interface{} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  | // NewUser() | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | // NewUserRequest request a new user is created | ||||||
|  | type NewUserRequest struct { | ||||||
|  | 	// UsernameConfig is metadata that can be used to generate a username | ||||||
|  | 	// within the database plugin | ||||||
|  | 	UsernameConfig UsernameMetadata | ||||||
|  |  | ||||||
|  | 	// Statements is an ordered list of commands to run within the database when | ||||||
|  | 	// creating a new user. This frequently includes permissions to give the | ||||||
|  | 	// user or similar actions. | ||||||
|  | 	Statements Statements | ||||||
|  |  | ||||||
|  | 	// RollbackStatements is an ordered list of commands to run within the database | ||||||
|  | 	// if the new user creation process fails. | ||||||
|  | 	RollbackStatements Statements | ||||||
|  |  | ||||||
|  | 	// Password credentials to use when creating the user | ||||||
|  | 	Password string | ||||||
|  |  | ||||||
|  | 	// Expiration of the user. Not all database plugins will support this. | ||||||
|  | 	Expiration time.Time | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // UsernameMetadata is metadata the database plugin can use to generate a username | ||||||
|  | type UsernameMetadata struct { | ||||||
|  | 	DisplayName string | ||||||
|  | 	RoleName    string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewUserResponse returns any information Vault needs to know after creating a new user. | ||||||
|  | type NewUserResponse struct { | ||||||
|  | 	// Username of the user created within the database. | ||||||
|  | 	// REQUIRED so Vault knows the name of the user that was created | ||||||
|  | 	Username string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  | // UpdateUser() | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | type UpdateUserRequest struct { | ||||||
|  | 	// Username to make changes to. | ||||||
|  | 	Username string | ||||||
|  |  | ||||||
|  | 	// Password indicates the new password to change to. | ||||||
|  | 	// If nil, no change is requested. | ||||||
|  | 	Password *ChangePassword | ||||||
|  |  | ||||||
|  | 	// Expiration indicates the new expiration date to change to. | ||||||
|  | 	// If nil, no change is requested. | ||||||
|  | 	Expiration *ChangeExpiration | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ChangePassword of a given user | ||||||
|  | type ChangePassword struct { | ||||||
|  | 	// NewPassword for the user | ||||||
|  | 	NewPassword string | ||||||
|  |  | ||||||
|  | 	// Statements is an ordered list of commands to run within the database | ||||||
|  | 	// when changing the user's password. | ||||||
|  | 	Statements Statements | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ChangeExpiration of a given user | ||||||
|  | type ChangeExpiration struct { | ||||||
|  | 	// NewExpiration of the user | ||||||
|  | 	NewExpiration time.Time | ||||||
|  |  | ||||||
|  | 	// Statements is an ordered list of commands to run within the database | ||||||
|  | 	// when changing the user's expiration. | ||||||
|  | 	Statements Statements | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type UpdateUserResponse struct{} | ||||||
|  |  | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  | // DeleteUser() | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | type DeleteUserRequest struct { | ||||||
|  | 	// Username to delete from the database | ||||||
|  | 	Username string | ||||||
|  |  | ||||||
|  | 	// Statements is an ordered list of commands to run within the database | ||||||
|  | 	// when deleting a user. | ||||||
|  | 	Statements Statements | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type DeleteUserResponse struct{} | ||||||
|  |  | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  | // Used across multiple functions | ||||||
|  | // /////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | // Statements wraps a collection of statements to run in a database when an | ||||||
|  | // operation is performed (create, update, etc.). This is a struct rather than | ||||||
|  | // a string slice so we can easily add more information to this in the future. | ||||||
|  | type Statements struct { | ||||||
|  | 	// Commands is an ordered list of commands to execute in the database. | ||||||
|  | 	// These commands may include templated fields such as {{username}} and {{password}} | ||||||
|  | 	Commands []string | ||||||
|  | } | ||||||
							
								
								
									
										254
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_client.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_client.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,254 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/golang/protobuf/ptypes" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/helper/pluginutil" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	_ Database = gRPCClient{} | ||||||
|  |  | ||||||
|  | 	ErrPluginShutdown = errors.New("plugin shutdown") | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type gRPCClient struct { | ||||||
|  | 	client  proto.DatabaseClient | ||||||
|  | 	doneCtx context.Context | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c gRPCClient) Initialize(ctx context.Context, req InitializeRequest) (InitializeResponse, error) { | ||||||
|  | 	rpcReq, err := initReqToProto(req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return InitializeResponse{}, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcResp, err := c.client.Initialize(ctx, rpcReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return InitializeResponse{}, fmt.Errorf("unable to initialize: %s", err.Error()) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return initRespFromProto(rpcResp) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func initReqToProto(req InitializeRequest) (*proto.InitializeRequest, error) { | ||||||
|  | 	config, err := mapToStruct(req.Config) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("unable to marshal config: %w", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcReq := &proto.InitializeRequest{ | ||||||
|  | 		ConfigData:       config, | ||||||
|  | 		VerifyConnection: req.VerifyConnection, | ||||||
|  | 	} | ||||||
|  | 	return rpcReq, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func initRespFromProto(rpcResp *proto.InitializeResponse) (InitializeResponse, error) { | ||||||
|  | 	newConfig := structToMap(rpcResp.GetConfigData()) | ||||||
|  |  | ||||||
|  | 	resp := InitializeResponse{ | ||||||
|  | 		Config: newConfig, | ||||||
|  | 	} | ||||||
|  | 	return resp, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c gRPCClient) NewUser(ctx context.Context, req NewUserRequest) (NewUserResponse, error) { | ||||||
|  | 	ctx, cancel := context.WithCancel(ctx) | ||||||
|  | 	quitCh := pluginutil.CtxCancelIfCanceled(cancel, c.doneCtx) | ||||||
|  | 	defer close(quitCh) | ||||||
|  | 	defer cancel() | ||||||
|  |  | ||||||
|  | 	rpcReq, err := newUserReqToProto(req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return NewUserResponse{}, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcResp, err := c.client.NewUser(ctx, rpcReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if c.doneCtx.Err() != nil { | ||||||
|  | 			return NewUserResponse{}, ErrPluginShutdown | ||||||
|  | 		} | ||||||
|  | 		return NewUserResponse{}, fmt.Errorf("unable to create new user: %w", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return newUserRespFromProto(rpcResp) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newUserReqToProto(req NewUserRequest) (*proto.NewUserRequest, error) { | ||||||
|  | 	if req.Password == "" { | ||||||
|  | 		return nil, fmt.Errorf("missing password") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	expiration, err := ptypes.TimestampProto(req.Expiration) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("unable to marshal expiration date: %w", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcReq := &proto.NewUserRequest{ | ||||||
|  | 		UsernameConfig: &proto.UsernameConfig{ | ||||||
|  | 			DisplayName: req.UsernameConfig.DisplayName, | ||||||
|  | 			RoleName:    req.UsernameConfig.RoleName, | ||||||
|  | 		}, | ||||||
|  | 		Password:   req.Password, | ||||||
|  | 		Expiration: expiration, | ||||||
|  | 		Statements: &proto.Statements{ | ||||||
|  | 			Commands: req.Statements.Commands, | ||||||
|  | 		}, | ||||||
|  | 		RollbackStatements: &proto.Statements{ | ||||||
|  | 			Commands: req.RollbackStatements.Commands, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	return rpcReq, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newUserRespFromProto(rpcResp *proto.NewUserResponse) (NewUserResponse, error) { | ||||||
|  | 	resp := NewUserResponse{ | ||||||
|  | 		Username: rpcResp.GetUsername(), | ||||||
|  | 	} | ||||||
|  | 	return resp, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c gRPCClient) UpdateUser(ctx context.Context, req UpdateUserRequest) (UpdateUserResponse, error) { | ||||||
|  | 	rpcReq, err := updateUserReqToProto(req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return UpdateUserResponse{}, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcResp, err := c.client.UpdateUser(ctx, rpcReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if c.doneCtx.Err() != nil { | ||||||
|  | 			return UpdateUserResponse{}, ErrPluginShutdown | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return UpdateUserResponse{}, fmt.Errorf("unable to update user: %w", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return updateUserRespFromProto(rpcResp) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func updateUserReqToProto(req UpdateUserRequest) (*proto.UpdateUserRequest, error) { | ||||||
|  | 	if req.Username == "" { | ||||||
|  | 		return nil, fmt.Errorf("missing username") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (req.Password == nil || req.Password.NewPassword == "") && | ||||||
|  | 		(req.Expiration == nil || req.Expiration.NewExpiration.IsZero()) { | ||||||
|  | 		return nil, fmt.Errorf("missing changes") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	expiration, err := expirationToProto(req.Expiration) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("unable to parse new expiration date: %w", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var password *proto.ChangePassword | ||||||
|  | 	if req.Password != nil && req.Password.NewPassword != "" { | ||||||
|  | 		password = &proto.ChangePassword{ | ||||||
|  | 			NewPassword: req.Password.NewPassword, | ||||||
|  | 			Statements: &proto.Statements{ | ||||||
|  | 				Commands: req.Password.Statements.Commands, | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcReq := &proto.UpdateUserRequest{ | ||||||
|  | 		Username:   req.Username, | ||||||
|  | 		Password:   password, | ||||||
|  | 		Expiration: expiration, | ||||||
|  | 	} | ||||||
|  | 	return rpcReq, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func updateUserRespFromProto(rpcResp *proto.UpdateUserResponse) (UpdateUserResponse, error) { | ||||||
|  | 	// Placeholder for future conversion if data is returned | ||||||
|  | 	return UpdateUserResponse{}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func expirationToProto(exp *ChangeExpiration) (*proto.ChangeExpiration, error) { | ||||||
|  | 	if exp == nil { | ||||||
|  | 		return nil, nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	expiration, err := ptypes.TimestampProto(exp.NewExpiration) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	changeExp := &proto.ChangeExpiration{ | ||||||
|  | 		NewExpiration: expiration, | ||||||
|  | 		Statements: &proto.Statements{ | ||||||
|  | 			Commands: exp.Statements.Commands, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	return changeExp, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c gRPCClient) DeleteUser(ctx context.Context, req DeleteUserRequest) (DeleteUserResponse, error) { | ||||||
|  | 	rpcReq, err := deleteUserReqToProto(req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return DeleteUserResponse{}, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcResp, err := c.client.DeleteUser(ctx, rpcReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if c.doneCtx.Err() != nil { | ||||||
|  | 			return DeleteUserResponse{}, ErrPluginShutdown | ||||||
|  | 		} | ||||||
|  | 		return DeleteUserResponse{}, fmt.Errorf("unable to update user: %w", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return deleteUserRespFromProto(rpcResp) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func deleteUserReqToProto(req DeleteUserRequest) (*proto.DeleteUserRequest, error) { | ||||||
|  | 	if req.Username == "" { | ||||||
|  | 		return nil, fmt.Errorf("missing username") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rpcReq := &proto.DeleteUserRequest{ | ||||||
|  | 		Username: req.Username, | ||||||
|  | 		Statements: &proto.Statements{ | ||||||
|  | 			Commands: req.Statements.Commands, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	return rpcReq, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func deleteUserRespFromProto(rpcResp *proto.DeleteUserResponse) (DeleteUserResponse, error) { | ||||||
|  | 	// Placeholder for future conversion if data is returned | ||||||
|  | 	return DeleteUserResponse{}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c gRPCClient) Type() (string, error) { | ||||||
|  | 	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) | ||||||
|  | 	defer cancel() | ||||||
|  |  | ||||||
|  | 	typeResp, err := c.client.Type(ctx, &proto.Empty{}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if c.doneCtx.Err() != nil { | ||||||
|  | 			return "", ErrPluginShutdown | ||||||
|  | 		} | ||||||
|  | 		return "", fmt.Errorf("unable to get database plugin type: %w", err) | ||||||
|  | 	} | ||||||
|  | 	return typeResp.GetType(), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c gRPCClient) Close() error { | ||||||
|  | 	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) | ||||||
|  | 	defer cancel() | ||||||
|  |  | ||||||
|  | 	_, err := c.client.Close(ctx, &proto.Empty{}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		if c.doneCtx.Err() != nil { | ||||||
|  | 			return ErrPluginShutdown | ||||||
|  | 		} | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_database_plugin.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_database_plugin.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/go-plugin" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
|  | 	"google.golang.org/grpc" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // handshakeConfigs are used to just do a basic handshake between | ||||||
|  | // a plugin and host. If the handshake fails, a user friendly error is shown. | ||||||
|  | // This prevents users from executing bad plugins or executing a plugin | ||||||
|  | // directory. It is a UX feature, not a security feature. | ||||||
|  | var handshakeConfig = plugin.HandshakeConfig{ | ||||||
|  | 	ProtocolVersion:  5, | ||||||
|  | 	MagicCookieKey:   "VAULT_DATABASE_PLUGIN", | ||||||
|  | 	MagicCookieValue: "926a0820-aea2-be28-51d6-83cdf00e8edb", | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type GRPCDatabasePlugin struct { | ||||||
|  | 	Impl Database | ||||||
|  |  | ||||||
|  | 	// Embeding this will disable the netRPC protocol | ||||||
|  | 	plugin.NetRPCUnsupportedPlugin | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var _ plugin.Plugin = &GRPCDatabasePlugin{} | ||||||
|  | var _ plugin.GRPCPlugin = &GRPCDatabasePlugin{} | ||||||
|  |  | ||||||
|  | func (d GRPCDatabasePlugin) GRPCServer(_ *plugin.GRPCBroker, s *grpc.Server) error { | ||||||
|  | 	proto.RegisterDatabaseServer(s, gRPCServer{impl: d.Impl}) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (GRPCDatabasePlugin) GRPCClient(doneCtx context.Context, _ *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) { | ||||||
|  | 	client := gRPCClient{ | ||||||
|  | 		client:  proto.NewDatabaseClient(c), | ||||||
|  | 		doneCtx: doneCtx, | ||||||
|  | 	} | ||||||
|  | 	return client, nil | ||||||
|  | } | ||||||
							
								
								
									
										190
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_server.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_server.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,190 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/golang/protobuf/ptypes" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
|  | 	"google.golang.org/grpc/codes" | ||||||
|  | 	"google.golang.org/grpc/status" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var _ proto.DatabaseServer = gRPCServer{} | ||||||
|  |  | ||||||
|  | type gRPCServer struct { | ||||||
|  | 	impl Database | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Initialize the database plugin | ||||||
|  | func (g gRPCServer) Initialize(ctx context.Context, request *proto.InitializeRequest) (*proto.InitializeResponse, error) { | ||||||
|  | 	rawConfig := structToMap(request.ConfigData) | ||||||
|  |  | ||||||
|  | 	dbReq := InitializeRequest{ | ||||||
|  | 		Config:           rawConfig, | ||||||
|  | 		VerifyConnection: request.VerifyConnection, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dbResp, err := g.impl.Initialize(ctx, dbReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.InitializeResponse{}, status.Errorf(codes.Internal, "failed to initialize: %s", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	newConfig, err := mapToStruct(dbResp.Config) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.InitializeResponse{}, status.Errorf(codes.Internal, "failed to marshal new config to JSON: %s", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	resp := &proto.InitializeResponse{ | ||||||
|  | 		ConfigData: newConfig, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return resp, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (g gRPCServer) NewUser(ctx context.Context, req *proto.NewUserRequest) (*proto.NewUserResponse, error) { | ||||||
|  | 	if req.GetUsernameConfig() == nil { | ||||||
|  | 		return &proto.NewUserResponse{}, status.Errorf(codes.InvalidArgument, "missing username config") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var expiration time.Time | ||||||
|  |  | ||||||
|  | 	if req.GetExpiration() != nil { | ||||||
|  | 		exp, err := ptypes.Timestamp(req.GetExpiration()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return &proto.NewUserResponse{}, status.Errorf(codes.InvalidArgument, "unable to parse expiration date: %s", err) | ||||||
|  | 		} | ||||||
|  | 		expiration = exp | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dbReq := NewUserRequest{ | ||||||
|  | 		UsernameConfig: UsernameMetadata{ | ||||||
|  | 			DisplayName: req.GetUsernameConfig().GetDisplayName(), | ||||||
|  | 			RoleName:    req.GetUsernameConfig().GetRoleName(), | ||||||
|  | 		}, | ||||||
|  | 		Password:           req.GetPassword(), | ||||||
|  | 		Expiration:         expiration, | ||||||
|  | 		Statements:         getStatementsFromProto(req.GetStatements()), | ||||||
|  | 		RollbackStatements: getStatementsFromProto(req.GetRollbackStatements()), | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dbResp, err := g.impl.NewUser(ctx, dbReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.NewUserResponse{}, status.Errorf(codes.Internal, "unable to create new user: %s", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	resp := &proto.NewUserResponse{ | ||||||
|  | 		Username: dbResp.Username, | ||||||
|  | 	} | ||||||
|  | 	return resp, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (g gRPCServer) UpdateUser(ctx context.Context, req *proto.UpdateUserRequest) (*proto.UpdateUserResponse, error) { | ||||||
|  | 	if req.GetUsername() == "" { | ||||||
|  | 		return &proto.UpdateUserResponse{}, status.Errorf(codes.InvalidArgument, "no username provided") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dbReq, err := getUpdateUserRequest(req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.UpdateUserResponse{}, status.Errorf(codes.InvalidArgument, err.Error()) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	_, err = g.impl.UpdateUser(ctx, dbReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.UpdateUserResponse{}, status.Errorf(codes.Internal, "unable to update user: %s", err) | ||||||
|  | 	} | ||||||
|  | 	return &proto.UpdateUserResponse{}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func getUpdateUserRequest(req *proto.UpdateUserRequest) (UpdateUserRequest, error) { | ||||||
|  | 	var password *ChangePassword | ||||||
|  | 	if req.GetPassword() != nil && req.GetPassword().GetNewPassword() != "" { | ||||||
|  | 		password = &ChangePassword{ | ||||||
|  | 			NewPassword: req.GetPassword().GetNewPassword(), | ||||||
|  | 			Statements:  getStatementsFromProto(req.GetPassword().GetStatements()), | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var expiration *ChangeExpiration | ||||||
|  | 	if req.GetExpiration() != nil && req.GetExpiration().GetNewExpiration() != nil { | ||||||
|  | 		newExpiration, err := ptypes.Timestamp(req.GetExpiration().GetNewExpiration()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return UpdateUserRequest{}, fmt.Errorf("unable to parse new expiration: %w", err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		expiration = &ChangeExpiration{ | ||||||
|  | 			NewExpiration: newExpiration, | ||||||
|  | 			Statements:    getStatementsFromProto(req.GetExpiration().GetStatements()), | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dbReq := UpdateUserRequest{ | ||||||
|  | 		Username:   req.GetUsername(), | ||||||
|  | 		Password:   password, | ||||||
|  | 		Expiration: expiration, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if !hasChange(dbReq) { | ||||||
|  | 		return UpdateUserRequest{}, fmt.Errorf("update user request has no changes") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return dbReq, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func hasChange(dbReq UpdateUserRequest) bool { | ||||||
|  | 	if dbReq.Password != nil && dbReq.Password.NewPassword != "" { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 	if dbReq.Expiration != nil && !dbReq.Expiration.NewExpiration.IsZero() { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (g gRPCServer) DeleteUser(ctx context.Context, req *proto.DeleteUserRequest) (*proto.DeleteUserResponse, error) { | ||||||
|  | 	if req.GetUsername() == "" { | ||||||
|  | 		return &proto.DeleteUserResponse{}, status.Errorf(codes.InvalidArgument, "no username provided") | ||||||
|  | 	} | ||||||
|  | 	dbReq := DeleteUserRequest{ | ||||||
|  | 		Username:   req.GetUsername(), | ||||||
|  | 		Statements: getStatementsFromProto(req.GetStatements()), | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	_, err := g.impl.DeleteUser(ctx, dbReq) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.DeleteUserResponse{}, status.Errorf(codes.Internal, "unable to delete user: %s", err) | ||||||
|  | 	} | ||||||
|  | 	return &proto.DeleteUserResponse{}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (g gRPCServer) Type(ctx context.Context, _ *proto.Empty) (*proto.TypeResponse, error) { | ||||||
|  | 	t, err := g.impl.Type() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.TypeResponse{}, status.Errorf(codes.Internal, "unable to retrieve type: %s", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	resp := &proto.TypeResponse{ | ||||||
|  | 		Type: t, | ||||||
|  | 	} | ||||||
|  | 	return resp, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (g gRPCServer) Close(ctx context.Context, _ *proto.Empty) (*proto.Empty, error) { | ||||||
|  | 	err := g.impl.Close() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &proto.Empty{}, status.Errorf(codes.Internal, "unable to close database plugin: %s", err) | ||||||
|  | 	} | ||||||
|  | 	return &proto.Empty{}, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func getStatementsFromProto(protoStmts *proto.Statements) (statements Statements) { | ||||||
|  | 	if protoStmts == nil { | ||||||
|  | 		return statements | ||||||
|  | 	} | ||||||
|  | 	cmds := protoStmts.GetCommands() | ||||||
|  | 	statements = Statements{ | ||||||
|  | 		Commands: cmds, | ||||||
|  | 	} | ||||||
|  | 	return statements | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/marshalling.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/marshalling.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"math" | ||||||
|  |  | ||||||
|  | 	"google.golang.org/protobuf/types/known/structpb" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func mapToStruct(m map[string]interface{}) (*structpb.Struct, error) { | ||||||
|  | 	return structpb.NewStruct(m) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func structToMap(strct *structpb.Struct) map[string]interface{} { | ||||||
|  | 	m := strct.AsMap() | ||||||
|  | 	coerceFloatsToInt(m) | ||||||
|  | 	return m | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // coerceFloatsToInt if the floats can be coerced to an integer without losing data | ||||||
|  | func coerceFloatsToInt(m map[string]interface{}) { | ||||||
|  | 	for k, v := range m { | ||||||
|  | 		fVal, ok := v.(float64) | ||||||
|  | 		if !ok { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		if isInt(fVal) { | ||||||
|  | 			m[k] = int64(fVal) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // isInt attempts to determine if the given floating point number could be represented as an integer without losing data | ||||||
|  | // This does not work for very large floats, however in this usage that's okay since we don't expect numbers that large. | ||||||
|  | func isInt(f float64) bool { | ||||||
|  | 	return math.Floor(f) == f | ||||||
|  | } | ||||||
							
								
								
									
										274
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/middleware.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/middleware.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,274 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"errors" | ||||||
|  | 	"net/url" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	metrics "github.com/armon/go-metrics" | ||||||
|  | 	"github.com/hashicorp/errwrap" | ||||||
|  | 	log "github.com/hashicorp/go-hclog" | ||||||
|  | 	"google.golang.org/grpc/status" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // /////////////////////////////////////////////////// | ||||||
|  | // Tracing Middleware | ||||||
|  | // /////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | var _ Database = databaseTracingMiddleware{} | ||||||
|  |  | ||||||
|  | // databaseTracingMiddleware wraps a implementation of Database and executes | ||||||
|  | // trace logging on function call. | ||||||
|  | type databaseTracingMiddleware struct { | ||||||
|  | 	next   Database | ||||||
|  | 	logger log.Logger | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseTracingMiddleware) Initialize(ctx context.Context, req InitializeRequest) (resp InitializeResponse, err error) { | ||||||
|  | 	defer func(then time.Time) { | ||||||
|  | 		mw.logger.Trace("initialize", | ||||||
|  | 			"status", "finished", | ||||||
|  | 			"verify", req.VerifyConnection, | ||||||
|  | 			"err", err, | ||||||
|  | 			"took", time.Since(then)) | ||||||
|  | 	}(time.Now()) | ||||||
|  |  | ||||||
|  | 	mw.logger.Trace("initialize", "status", "started") | ||||||
|  | 	return mw.next.Initialize(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseTracingMiddleware) NewUser(ctx context.Context, req NewUserRequest) (resp NewUserResponse, 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.NewUser(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseTracingMiddleware) UpdateUser(ctx context.Context, req UpdateUserRequest) (resp UpdateUserResponse, err error) { | ||||||
|  | 	defer func(then time.Time) { | ||||||
|  | 		mw.logger.Trace("update user", | ||||||
|  | 			"status", "finished", | ||||||
|  | 			"err", err, | ||||||
|  | 			"took", time.Since(then)) | ||||||
|  | 	}(time.Now()) | ||||||
|  |  | ||||||
|  | 	mw.logger.Trace("update user", "status", "started") | ||||||
|  | 	return mw.next.UpdateUser(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseTracingMiddleware) DeleteUser(ctx context.Context, req DeleteUserRequest) (resp DeleteUserResponse, err error) { | ||||||
|  | 	defer func(then time.Time) { | ||||||
|  | 		mw.logger.Trace("delete user", | ||||||
|  | 			"status", "finished", | ||||||
|  | 			"err", err, | ||||||
|  | 			"took", time.Since(then)) | ||||||
|  | 	}(time.Now()) | ||||||
|  |  | ||||||
|  | 	mw.logger.Trace("delete user", | ||||||
|  | 		"status", "started") | ||||||
|  | 	return mw.next.DeleteUser(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseTracingMiddleware) Type() (string, error) { | ||||||
|  | 	return mw.next.Type() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  | // /////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | var _ Database = databaseMetricsMiddleware{} | ||||||
|  |  | ||||||
|  | // 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) Initialize(ctx context.Context, req InitializeRequest) (resp InitializeResponse, 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.Initialize(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseMetricsMiddleware) NewUser(ctx context.Context, req NewUserRequest) (resp NewUserResponse, err error) { | ||||||
|  | 	defer func(start time.Time) { | ||||||
|  | 		metrics.MeasureSince([]string{"database", "NewUser"}, start) | ||||||
|  | 		metrics.MeasureSince([]string{"database", mw.typeStr, "NewUser"}, start) | ||||||
|  |  | ||||||
|  | 		if err != nil { | ||||||
|  | 			metrics.IncrCounter([]string{"database", "NewUser", "error"}, 1) | ||||||
|  | 			metrics.IncrCounter([]string{"database", mw.typeStr, "NewUser", "error"}, 1) | ||||||
|  | 		} | ||||||
|  | 	}(time.Now()) | ||||||
|  |  | ||||||
|  | 	metrics.IncrCounter([]string{"database", "NewUser"}, 1) | ||||||
|  | 	metrics.IncrCounter([]string{"database", mw.typeStr, "NewUser"}, 1) | ||||||
|  | 	return mw.next.NewUser(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseMetricsMiddleware) UpdateUser(ctx context.Context, req UpdateUserRequest) (resp UpdateUserResponse, err error) { | ||||||
|  | 	defer func(now time.Time) { | ||||||
|  | 		metrics.MeasureSince([]string{"database", "UpdateUser"}, now) | ||||||
|  | 		metrics.MeasureSince([]string{"database", mw.typeStr, "UpdateUser"}, now) | ||||||
|  |  | ||||||
|  | 		if err != nil { | ||||||
|  | 			metrics.IncrCounter([]string{"database", "UpdateUser", "error"}, 1) | ||||||
|  | 			metrics.IncrCounter([]string{"database", mw.typeStr, "UpdateUser", "error"}, 1) | ||||||
|  | 		} | ||||||
|  | 	}(time.Now()) | ||||||
|  |  | ||||||
|  | 	metrics.IncrCounter([]string{"database", "UpdateUser"}, 1) | ||||||
|  | 	metrics.IncrCounter([]string{"database", mw.typeStr, "UpdateUser"}, 1) | ||||||
|  | 	return mw.next.UpdateUser(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseMetricsMiddleware) DeleteUser(ctx context.Context, req DeleteUserRequest) (resp DeleteUserResponse, err error) { | ||||||
|  | 	defer func(now time.Time) { | ||||||
|  | 		metrics.MeasureSince([]string{"database", "DeleteUser"}, now) | ||||||
|  | 		metrics.MeasureSince([]string{"database", mw.typeStr, "DeleteUser"}, now) | ||||||
|  |  | ||||||
|  | 		if err != nil { | ||||||
|  | 			metrics.IncrCounter([]string{"database", "DeleteUser", "error"}, 1) | ||||||
|  | 			metrics.IncrCounter([]string{"database", mw.typeStr, "DeleteUser", "error"}, 1) | ||||||
|  | 		} | ||||||
|  | 	}(time.Now()) | ||||||
|  |  | ||||||
|  | 	metrics.IncrCounter([]string{"database", "DeleteUser"}, 1) | ||||||
|  | 	metrics.IncrCounter([]string{"database", mw.typeStr, "DeleteUser"}, 1) | ||||||
|  | 	return mw.next.DeleteUser(ctx, req) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw databaseMetricsMiddleware) Type() (string, error) { | ||||||
|  | 	return mw.next.Type() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  | // /////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | var _ Database = DatabaseErrorSanitizerMiddleware{} | ||||||
|  |  | ||||||
|  | // DatabaseErrorSanitizerMiddleware wraps an implementation of Databases and | ||||||
|  | // sanitizes returned error messages | ||||||
|  | type DatabaseErrorSanitizerMiddleware struct { | ||||||
|  | 	next      Database | ||||||
|  | 	secretsFn secretsFn | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type secretsFn func() map[string]string | ||||||
|  |  | ||||||
|  | func NewDatabaseErrorSanitizerMiddleware(next Database, secrets secretsFn) DatabaseErrorSanitizerMiddleware { | ||||||
|  | 	return DatabaseErrorSanitizerMiddleware{ | ||||||
|  | 		next:      next, | ||||||
|  | 		secretsFn: secrets, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw DatabaseErrorSanitizerMiddleware) Initialize(ctx context.Context, req InitializeRequest) (resp InitializeResponse, err error) { | ||||||
|  | 	resp, err = mw.next.Initialize(ctx, req) | ||||||
|  | 	return resp, mw.sanitize(err) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw DatabaseErrorSanitizerMiddleware) NewUser(ctx context.Context, req NewUserRequest) (resp NewUserResponse, err error) { | ||||||
|  | 	resp, err = mw.next.NewUser(ctx, req) | ||||||
|  | 	return resp, mw.sanitize(err) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw DatabaseErrorSanitizerMiddleware) UpdateUser(ctx context.Context, req UpdateUserRequest) (UpdateUserResponse, error) { | ||||||
|  | 	resp, err := mw.next.UpdateUser(ctx, req) | ||||||
|  | 	return resp, mw.sanitize(err) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw DatabaseErrorSanitizerMiddleware) DeleteUser(ctx context.Context, req DeleteUserRequest) (DeleteUserResponse, error) { | ||||||
|  | 	resp, err := mw.next.DeleteUser(ctx, req) | ||||||
|  | 	return resp, mw.sanitize(err) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw DatabaseErrorSanitizerMiddleware) Type() (string, error) { | ||||||
|  | 	dbType, err := mw.next.Type() | ||||||
|  | 	return dbType, mw.sanitize(err) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (mw DatabaseErrorSanitizerMiddleware) Close() (err error) { | ||||||
|  | 	return mw.sanitize(mw.next.Close()) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // sanitize errors by removing any sensitive strings within their messages. This uses | ||||||
|  | // the secretsFn to determine what fields should be sanitized. | ||||||
|  | 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 { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	for find, replace := range mw.secretsFn() { | ||||||
|  | 		if find == "" { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// Attempt to keep the status code attached to the | ||||||
|  | 		// error while changing the actual error message | ||||||
|  | 		s, ok := status.FromError(err) | ||||||
|  | 		if ok { | ||||||
|  | 			err = status.Error(s.Code(), strings.Replace(s.Message(), find, replace, -1)) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		err = errors.New(strings.Replace(err.Error(), find, replace, -1)) | ||||||
|  | 	} | ||||||
|  | 	return err | ||||||
|  | } | ||||||
							
								
								
									
										81
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_client.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_client.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | |||||||
|  | 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{ | ||||||
|  | 		5: plugin.PluginSet{ | ||||||
|  | 			"database": new(GRPCDatabasePlugin), | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	client, err := pluginRunner.RunConfig(ctx, | ||||||
|  | 		pluginutil.Runner(sys), | ||||||
|  | 		pluginutil.PluginSets(pluginSets), | ||||||
|  | 		pluginutil.HandshakeConfig(handshakeConfig), | ||||||
|  | 		pluginutil.Logger(logger), | ||||||
|  | 		pluginutil.MetadataMode(isMetadataMode), | ||||||
|  | 		pluginutil.AutoMTLS(false), | ||||||
|  | 	) | ||||||
|  | 	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 | ||||||
|  | } | ||||||
							
								
								
									
										78
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_factory.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_factory.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"fmt" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/errwrap" | ||||||
|  | 	log "github.com/hashicorp/go-hclog" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/helper/consts" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/helper/pluginutil" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // 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 | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_server.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_server.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | package dbplugin | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"crypto/tls" | ||||||
|  | 	"fmt" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/go-plugin" | ||||||
|  | 	"github.com/hashicorp/vault/sdk/helper/pluginutil" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // 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 { | ||||||
|  | 	err := pluginutil.OptionallyEnableMlock() | ||||||
|  | 	if err != nil { | ||||||
|  | 		fmt.Println(err) | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// pluginSets is the map of plugins we can dispense. | ||||||
|  | 	pluginSets := map[int]plugin.PluginSet{ | ||||||
|  | 		5: plugin.PluginSet{ | ||||||
|  | 			"database": &GRPCDatabasePlugin{ | ||||||
|  | 				Impl: db, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	conf := &plugin.ServeConfig{ | ||||||
|  | 		HandshakeConfig:  handshakeConfig, | ||||||
|  | 		VersionedPlugins: pluginSets, | ||||||
|  | 		GRPCServer:       plugin.DefaultGRPCServer, | ||||||
|  | 		TLSProvider:      tlsProvider, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return conf | ||||||
|  | } | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| // versions: | // versions: | ||||||
| // 	protoc-gen-go v1.23.0 | // 	protoc-gen-go v1.23.0 | ||||||
| // 	protoc        v3.13.0 | // 	protoc        v3.13.0 | ||||||
| // source: sdk/database/newdbplugin/proto/database.proto | // source: sdk/database/dbplugin/v5/proto/database.proto | ||||||
| 
 | 
 | ||||||
| package proto | package proto | ||||||
| 
 | 
 | ||||||
| @@ -46,7 +46,7 @@ type InitializeRequest struct { | |||||||
| func (x *InitializeRequest) Reset() { | func (x *InitializeRequest) Reset() { | ||||||
| 	*x = InitializeRequest{} | 	*x = InitializeRequest{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[0] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[0] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -59,7 +59,7 @@ func (x *InitializeRequest) String() string { | |||||||
| func (*InitializeRequest) ProtoMessage() {} | func (*InitializeRequest) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *InitializeRequest) ProtoReflect() protoreflect.Message { | func (x *InitializeRequest) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[0] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[0] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -72,7 +72,7 @@ func (x *InitializeRequest) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use InitializeRequest.ProtoReflect.Descriptor instead. | // Deprecated: Use InitializeRequest.ProtoReflect.Descriptor instead. | ||||||
| func (*InitializeRequest) Descriptor() ([]byte, []int) { | func (*InitializeRequest) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{0} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{0} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *InitializeRequest) GetConfigData() *_struct.Struct { | func (x *InitializeRequest) GetConfigData() *_struct.Struct { | ||||||
| @@ -100,7 +100,7 @@ type InitializeResponse struct { | |||||||
| func (x *InitializeResponse) Reset() { | func (x *InitializeResponse) Reset() { | ||||||
| 	*x = InitializeResponse{} | 	*x = InitializeResponse{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[1] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[1] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -113,7 +113,7 @@ func (x *InitializeResponse) String() string { | |||||||
| func (*InitializeResponse) ProtoMessage() {} | func (*InitializeResponse) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *InitializeResponse) ProtoReflect() protoreflect.Message { | func (x *InitializeResponse) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[1] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[1] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -126,7 +126,7 @@ func (x *InitializeResponse) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use InitializeResponse.ProtoReflect.Descriptor instead. | // Deprecated: Use InitializeResponse.ProtoReflect.Descriptor instead. | ||||||
| func (*InitializeResponse) Descriptor() ([]byte, []int) { | func (*InitializeResponse) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{1} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{1} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *InitializeResponse) GetConfigData() *_struct.Struct { | func (x *InitializeResponse) GetConfigData() *_struct.Struct { | ||||||
| @@ -151,7 +151,7 @@ type NewUserRequest struct { | |||||||
| func (x *NewUserRequest) Reset() { | func (x *NewUserRequest) Reset() { | ||||||
| 	*x = NewUserRequest{} | 	*x = NewUserRequest{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[2] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[2] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -164,7 +164,7 @@ func (x *NewUserRequest) String() string { | |||||||
| func (*NewUserRequest) ProtoMessage() {} | func (*NewUserRequest) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *NewUserRequest) ProtoReflect() protoreflect.Message { | func (x *NewUserRequest) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[2] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[2] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -177,7 +177,7 @@ func (x *NewUserRequest) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use NewUserRequest.ProtoReflect.Descriptor instead. | // Deprecated: Use NewUserRequest.ProtoReflect.Descriptor instead. | ||||||
| func (*NewUserRequest) Descriptor() ([]byte, []int) { | func (*NewUserRequest) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{2} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{2} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *NewUserRequest) GetUsernameConfig() *UsernameConfig { | func (x *NewUserRequest) GetUsernameConfig() *UsernameConfig { | ||||||
| @@ -227,7 +227,7 @@ type UsernameConfig struct { | |||||||
| func (x *UsernameConfig) Reset() { | func (x *UsernameConfig) Reset() { | ||||||
| 	*x = UsernameConfig{} | 	*x = UsernameConfig{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[3] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[3] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -240,7 +240,7 @@ func (x *UsernameConfig) String() string { | |||||||
| func (*UsernameConfig) ProtoMessage() {} | func (*UsernameConfig) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *UsernameConfig) ProtoReflect() protoreflect.Message { | func (x *UsernameConfig) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[3] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[3] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -253,7 +253,7 @@ func (x *UsernameConfig) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use UsernameConfig.ProtoReflect.Descriptor instead. | // Deprecated: Use UsernameConfig.ProtoReflect.Descriptor instead. | ||||||
| func (*UsernameConfig) Descriptor() ([]byte, []int) { | func (*UsernameConfig) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{3} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{3} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *UsernameConfig) GetDisplayName() string { | func (x *UsernameConfig) GetDisplayName() string { | ||||||
| @@ -281,7 +281,7 @@ type NewUserResponse struct { | |||||||
| func (x *NewUserResponse) Reset() { | func (x *NewUserResponse) Reset() { | ||||||
| 	*x = NewUserResponse{} | 	*x = NewUserResponse{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[4] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[4] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -294,7 +294,7 @@ func (x *NewUserResponse) String() string { | |||||||
| func (*NewUserResponse) ProtoMessage() {} | func (*NewUserResponse) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *NewUserResponse) ProtoReflect() protoreflect.Message { | func (x *NewUserResponse) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[4] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[4] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -307,7 +307,7 @@ func (x *NewUserResponse) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use NewUserResponse.ProtoReflect.Descriptor instead. | // Deprecated: Use NewUserResponse.ProtoReflect.Descriptor instead. | ||||||
| func (*NewUserResponse) Descriptor() ([]byte, []int) { | func (*NewUserResponse) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{4} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{4} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *NewUserResponse) GetUsername() string { | func (x *NewUserResponse) GetUsername() string { | ||||||
| @@ -333,7 +333,7 @@ type UpdateUserRequest struct { | |||||||
| func (x *UpdateUserRequest) Reset() { | func (x *UpdateUserRequest) Reset() { | ||||||
| 	*x = UpdateUserRequest{} | 	*x = UpdateUserRequest{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[5] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[5] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -346,7 +346,7 @@ func (x *UpdateUserRequest) String() string { | |||||||
| func (*UpdateUserRequest) ProtoMessage() {} | func (*UpdateUserRequest) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *UpdateUserRequest) ProtoReflect() protoreflect.Message { | func (x *UpdateUserRequest) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[5] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[5] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -359,7 +359,7 @@ func (x *UpdateUserRequest) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use UpdateUserRequest.ProtoReflect.Descriptor instead. | // Deprecated: Use UpdateUserRequest.ProtoReflect.Descriptor instead. | ||||||
| func (*UpdateUserRequest) Descriptor() ([]byte, []int) { | func (*UpdateUserRequest) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{5} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{5} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *UpdateUserRequest) GetUsername() string { | func (x *UpdateUserRequest) GetUsername() string { | ||||||
| @@ -395,7 +395,7 @@ type ChangePassword struct { | |||||||
| func (x *ChangePassword) Reset() { | func (x *ChangePassword) Reset() { | ||||||
| 	*x = ChangePassword{} | 	*x = ChangePassword{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[6] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[6] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -408,7 +408,7 @@ func (x *ChangePassword) String() string { | |||||||
| func (*ChangePassword) ProtoMessage() {} | func (*ChangePassword) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *ChangePassword) ProtoReflect() protoreflect.Message { | func (x *ChangePassword) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[6] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[6] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -421,7 +421,7 @@ func (x *ChangePassword) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use ChangePassword.ProtoReflect.Descriptor instead. | // Deprecated: Use ChangePassword.ProtoReflect.Descriptor instead. | ||||||
| func (*ChangePassword) Descriptor() ([]byte, []int) { | func (*ChangePassword) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{6} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{6} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *ChangePassword) GetNewPassword() string { | func (x *ChangePassword) GetNewPassword() string { | ||||||
| @@ -450,7 +450,7 @@ type ChangeExpiration struct { | |||||||
| func (x *ChangeExpiration) Reset() { | func (x *ChangeExpiration) Reset() { | ||||||
| 	*x = ChangeExpiration{} | 	*x = ChangeExpiration{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[7] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[7] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -463,7 +463,7 @@ func (x *ChangeExpiration) String() string { | |||||||
| func (*ChangeExpiration) ProtoMessage() {} | func (*ChangeExpiration) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *ChangeExpiration) ProtoReflect() protoreflect.Message { | func (x *ChangeExpiration) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[7] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[7] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -476,7 +476,7 @@ func (x *ChangeExpiration) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use ChangeExpiration.ProtoReflect.Descriptor instead. | // Deprecated: Use ChangeExpiration.ProtoReflect.Descriptor instead. | ||||||
| func (*ChangeExpiration) Descriptor() ([]byte, []int) { | func (*ChangeExpiration) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{7} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{7} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *ChangeExpiration) GetNewExpiration() *timestamp.Timestamp { | func (x *ChangeExpiration) GetNewExpiration() *timestamp.Timestamp { | ||||||
| @@ -502,7 +502,7 @@ type UpdateUserResponse struct { | |||||||
| func (x *UpdateUserResponse) Reset() { | func (x *UpdateUserResponse) Reset() { | ||||||
| 	*x = UpdateUserResponse{} | 	*x = UpdateUserResponse{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[8] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[8] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -515,7 +515,7 @@ func (x *UpdateUserResponse) String() string { | |||||||
| func (*UpdateUserResponse) ProtoMessage() {} | func (*UpdateUserResponse) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *UpdateUserResponse) ProtoReflect() protoreflect.Message { | func (x *UpdateUserResponse) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[8] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[8] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -528,7 +528,7 @@ func (x *UpdateUserResponse) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use UpdateUserResponse.ProtoReflect.Descriptor instead. | // Deprecated: Use UpdateUserResponse.ProtoReflect.Descriptor instead. | ||||||
| func (*UpdateUserResponse) Descriptor() ([]byte, []int) { | func (*UpdateUserResponse) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{8} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{8} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ///////////////// | ///////////////// | ||||||
| @@ -546,7 +546,7 @@ type DeleteUserRequest struct { | |||||||
| func (x *DeleteUserRequest) Reset() { | func (x *DeleteUserRequest) Reset() { | ||||||
| 	*x = DeleteUserRequest{} | 	*x = DeleteUserRequest{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[9] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[9] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -559,7 +559,7 @@ func (x *DeleteUserRequest) String() string { | |||||||
| func (*DeleteUserRequest) ProtoMessage() {} | func (*DeleteUserRequest) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *DeleteUserRequest) ProtoReflect() protoreflect.Message { | func (x *DeleteUserRequest) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[9] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[9] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -572,7 +572,7 @@ func (x *DeleteUserRequest) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use DeleteUserRequest.ProtoReflect.Descriptor instead. | // Deprecated: Use DeleteUserRequest.ProtoReflect.Descriptor instead. | ||||||
| func (*DeleteUserRequest) Descriptor() ([]byte, []int) { | func (*DeleteUserRequest) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{9} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{9} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *DeleteUserRequest) GetUsername() string { | func (x *DeleteUserRequest) GetUsername() string { | ||||||
| @@ -598,7 +598,7 @@ type DeleteUserResponse struct { | |||||||
| func (x *DeleteUserResponse) Reset() { | func (x *DeleteUserResponse) Reset() { | ||||||
| 	*x = DeleteUserResponse{} | 	*x = DeleteUserResponse{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[10] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[10] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -611,7 +611,7 @@ func (x *DeleteUserResponse) String() string { | |||||||
| func (*DeleteUserResponse) ProtoMessage() {} | func (*DeleteUserResponse) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *DeleteUserResponse) ProtoReflect() protoreflect.Message { | func (x *DeleteUserResponse) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[10] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[10] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -624,7 +624,7 @@ func (x *DeleteUserResponse) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use DeleteUserResponse.ProtoReflect.Descriptor instead. | // Deprecated: Use DeleteUserResponse.ProtoReflect.Descriptor instead. | ||||||
| func (*DeleteUserResponse) Descriptor() ([]byte, []int) { | func (*DeleteUserResponse) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{10} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{10} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ///////////////// | ///////////////// | ||||||
| @@ -641,7 +641,7 @@ type TypeResponse struct { | |||||||
| func (x *TypeResponse) Reset() { | func (x *TypeResponse) Reset() { | ||||||
| 	*x = TypeResponse{} | 	*x = TypeResponse{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[11] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[11] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -654,7 +654,7 @@ func (x *TypeResponse) String() string { | |||||||
| func (*TypeResponse) ProtoMessage() {} | func (*TypeResponse) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *TypeResponse) ProtoReflect() protoreflect.Message { | func (x *TypeResponse) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[11] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[11] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -667,7 +667,7 @@ func (x *TypeResponse) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use TypeResponse.ProtoReflect.Descriptor instead. | // Deprecated: Use TypeResponse.ProtoReflect.Descriptor instead. | ||||||
| func (*TypeResponse) Descriptor() ([]byte, []int) { | func (*TypeResponse) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{11} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{11} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *TypeResponse) GetType() string { | func (x *TypeResponse) GetType() string { | ||||||
| @@ -691,7 +691,7 @@ type Statements struct { | |||||||
| func (x *Statements) Reset() { | func (x *Statements) Reset() { | ||||||
| 	*x = Statements{} | 	*x = Statements{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[12] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[12] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -704,7 +704,7 @@ func (x *Statements) String() string { | |||||||
| func (*Statements) ProtoMessage() {} | func (*Statements) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *Statements) ProtoReflect() protoreflect.Message { | func (x *Statements) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[12] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[12] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -717,7 +717,7 @@ func (x *Statements) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use Statements.ProtoReflect.Descriptor instead. | // Deprecated: Use Statements.ProtoReflect.Descriptor instead. | ||||||
| func (*Statements) Descriptor() ([]byte, []int) { | func (*Statements) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{12} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{12} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (x *Statements) GetCommands() []string { | func (x *Statements) GetCommands() []string { | ||||||
| @@ -736,7 +736,7 @@ type Empty struct { | |||||||
| func (x *Empty) Reset() { | func (x *Empty) Reset() { | ||||||
| 	*x = Empty{} | 	*x = Empty{} | ||||||
| 	if protoimpl.UnsafeEnabled { | 	if protoimpl.UnsafeEnabled { | ||||||
| 		mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[13] | 		mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[13] | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		ms.StoreMessageInfo(mi) | 		ms.StoreMessageInfo(mi) | ||||||
| 	} | 	} | ||||||
| @@ -749,7 +749,7 @@ func (x *Empty) String() string { | |||||||
| func (*Empty) ProtoMessage() {} | func (*Empty) ProtoMessage() {} | ||||||
| 
 | 
 | ||||||
| func (x *Empty) ProtoReflect() protoreflect.Message { | func (x *Empty) ProtoReflect() protoreflect.Message { | ||||||
| 	mi := &file_sdk_database_newdbplugin_proto_database_proto_msgTypes[13] | 	mi := &file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[13] | ||||||
| 	if protoimpl.UnsafeEnabled && x != nil { | 	if protoimpl.UnsafeEnabled && x != nil { | ||||||
| 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||||||
| 		if ms.LoadMessageInfo() == nil { | 		if ms.LoadMessageInfo() == nil { | ||||||
| @@ -762,16 +762,16 @@ func (x *Empty) ProtoReflect() protoreflect.Message { | |||||||
| 
 | 
 | ||||||
| // Deprecated: Use Empty.ProtoReflect.Descriptor instead. | // Deprecated: Use Empty.ProtoReflect.Descriptor instead. | ||||||
| func (*Empty) Descriptor() ([]byte, []int) { | func (*Empty) Descriptor() ([]byte, []int) { | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP(), []int{13} | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP(), []int{13} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var File_sdk_database_newdbplugin_proto_database_proto protoreflect.FileDescriptor | var File_sdk_database_dbplugin_v5_proto_database_proto protoreflect.FileDescriptor | ||||||
| 
 | 
 | ||||||
| var file_sdk_database_newdbplugin_proto_database_proto_rawDesc = []byte{ | var file_sdk_database_dbplugin_v5_proto_database_proto_rawDesc = []byte{ | ||||||
| 	0x0a, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x6e, | 	0x0a, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x64, | ||||||
| 	0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, | 	0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, | ||||||
| 	0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, | 	0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, | ||||||
| 	0x0b, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x1a, 0x1c, 0x67, 0x6f, | 	0x0b, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x1a, 0x1c, 0x67, 0x6f, | ||||||
| 	0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, | 	0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, | ||||||
| 	0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, | 	0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, | ||||||
| 	0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, | 	0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, | ||||||
| @@ -791,8 +791,8 @@ var file_sdk_database_newdbplugin_proto_database_proto_rawDesc = []byte{ | |||||||
| 	0x66, 0x69, 0x67, 0x44, 0x61, 0x74, 0x61, 0x22, 0xb1, 0x02, 0x0a, 0x0e, 0x4e, 0x65, 0x77, 0x55, | 	0x66, 0x69, 0x67, 0x44, 0x61, 0x74, 0x61, 0x22, 0xb1, 0x02, 0x0a, 0x0e, 0x4e, 0x65, 0x77, 0x55, | ||||||
| 	0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x0f, 0x75, 0x73, | 	0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x0f, 0x75, 0x73, | ||||||
| 	0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, | 	0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, | ||||||
| 	0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, | 	0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, | ||||||
| 	0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, | 	0x35, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, | ||||||
| 	0x52, 0x0e, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, | 	0x52, 0x0e, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, | ||||||
| 	0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, | 	0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, | ||||||
| 	0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x3a, 0x0a, 0x0a, | 	0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x3a, 0x0a, 0x0a, | ||||||
| @@ -800,12 +800,12 @@ var file_sdk_database_newdbplugin_proto_database_proto_rawDesc = []byte{ | |||||||
| 	0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, | 	0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, | ||||||
| 	0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x65, 0x78, | 	0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x65, 0x78, | ||||||
| 	0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, | 	0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, | ||||||
| 	0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6e, | 	0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x64, | ||||||
| 	0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, | 	0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, | ||||||
| 	0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, | 	0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, | ||||||
| 	0x73, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x73, 0x74, | 	0x73, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x73, 0x74, | ||||||
| 	0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, | 	0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, | ||||||
| 	0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x53, 0x74, 0x61, | 	0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, 0x74, 0x61, | ||||||
| 	0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x12, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, | 	0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x12, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, | ||||||
| 	0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x50, 0x0a, 0x0e, 0x55, | 	0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x50, 0x0a, 0x0e, 0x55, | ||||||
| 	0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, | 	0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, | ||||||
| @@ -820,18 +820,18 @@ var file_sdk_database_newdbplugin_proto_database_proto_rawDesc = []byte{ | |||||||
| 	0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, | 	0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, | ||||||
| 	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, | 	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, | ||||||
| 	0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, | 	0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, | ||||||
| 	0x32, 0x1b, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, | 	0x32, 0x1b, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x43, | ||||||
| 	0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x08, 0x70, | 	0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x08, 0x70, | ||||||
| 	0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x3d, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, | 	0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x3d, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, | ||||||
| 	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6e, 0x65, | 	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x64, 0x62, | ||||||
| 	0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, | 	0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, | ||||||
| 	0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, | 	0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, | ||||||
| 	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x6c, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, | 	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x6c, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, | ||||||
| 	0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, | 	0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x77, 0x5f, | ||||||
| 	0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, | 	0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, | ||||||
| 	0x6e, 0x65, 0x77, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x37, 0x0a, 0x0a, 0x73, | 	0x6e, 0x65, 0x77, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x37, 0x0a, 0x0a, 0x73, | ||||||
| 	0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, | 	0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, | ||||||
| 	0x17, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x53, 0x74, | 	0x17, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, 0x74, | ||||||
| 	0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, | 	0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, | ||||||
| 	0x65, 0x6e, 0x74, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x10, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, | 	0x65, 0x6e, 0x74, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x10, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, | ||||||
| 	0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0e, 0x6e, 0x65, 0x77, | 	0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0e, 0x6e, 0x65, 0x77, | ||||||
| @@ -840,7 +840,7 @@ var file_sdk_database_newdbplugin_proto_database_proto_rawDesc = []byte{ | |||||||
| 	0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x6e, | 	0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x6e, | ||||||
| 	0x65, 0x77, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0a, | 	0x65, 0x77, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0a, | ||||||
| 	0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, | 	0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, | ||||||
| 	0x32, 0x17, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x53, | 	0x32, 0x17, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, | ||||||
| 	0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, | 	0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, | ||||||
| 	0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, | 	0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, | ||||||
| 	0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x68, 0x0a, 0x11, 0x44, | 	0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x68, 0x0a, 0x11, 0x44, | ||||||
| @@ -848,7 +848,7 @@ var file_sdk_database_newdbplugin_proto_database_proto_rawDesc = []byte{ | |||||||
| 	0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, | 	0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, | ||||||
| 	0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x0a, | 	0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x0a, | ||||||
| 	0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, | 	0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, | ||||||
| 	0x32, 0x17, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x53, | 	0x32, 0x17, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x53, | ||||||
| 	0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, | 	0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, | ||||||
| 	0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, | 	0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, | ||||||
| 	0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x0a, 0x0c, 0x54, | 	0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x0a, 0x0c, 0x54, | ||||||
| @@ -859,93 +859,93 @@ var file_sdk_database_newdbplugin_proto_database_proto_rawDesc = []byte{ | |||||||
| 	0x08, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, | 	0x08, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, | ||||||
| 	0x74, 0x79, 0x32, 0xa5, 0x03, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, | 	0x74, 0x79, 0x32, 0xa5, 0x03, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, | ||||||
| 	0x4d, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x1e, 0x2e, | 	0x4d, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x1e, 0x2e, | ||||||
| 	0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x49, 0x6e, 0x69, 0x74, | 	0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x49, 0x6e, 0x69, 0x74, | ||||||
| 	0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, | 	0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, | ||||||
| 	0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x49, 0x6e, 0x69, 0x74, | 	0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x49, 0x6e, 0x69, 0x74, | ||||||
| 	0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, | 	0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, | ||||||
| 	0x0a, 0x07, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x6e, 0x65, 0x77, 0x64, | 	0x0a, 0x07, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x64, 0x62, 0x70, 0x6c, | ||||||
| 	0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, | 	0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, | ||||||
| 	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, | 	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, | ||||||
| 	0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, | 	0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, | ||||||
| 	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, | 	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, | ||||||
| 	0x65, 0x72, 0x12, 0x1e, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, | 	0x65, 0x72, 0x12, 0x1e, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, | ||||||
| 	0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, | 	0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, | ||||||
| 	0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, | 	0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, | ||||||
| 	0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, | 	0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, | ||||||
| 	0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, | 	0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, | ||||||
| 	0x72, 0x12, 0x1e, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, | 	0x72, 0x12, 0x1e, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, | ||||||
| 	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, | 	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, | ||||||
| 	0x74, 0x1a, 0x1f, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, | 	0x74, 0x1a, 0x1f, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, | ||||||
| 	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, | 	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, | ||||||
| 	0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x2e, 0x6e, 0x65, 0x77, | 	0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x2e, 0x64, 0x62, 0x70, | ||||||
| 	0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, | 	0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, | ||||||
| 	0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x54, 0x79, 0x70, | 	0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x54, 0x79, 0x70, | ||||||
| 	0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x05, 0x43, 0x6c, 0x6f, | 	0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x05, 0x43, 0x6c, 0x6f, | ||||||
| 	0x73, 0x65, 0x12, 0x12, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, | 	0x73, 0x65, 0x12, 0x12, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, | ||||||
| 	0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, | 	0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, | ||||||
| 	0x75, 0x67, 0x69, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, | 	0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, | ||||||
| 	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, | 	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, | ||||||
| 	0x72, 0x70, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x64, 0x61, 0x74, | 	0x72, 0x70, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x64, 0x61, 0x74, | ||||||
| 	0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, | 	0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x76, | ||||||
| 	0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, | 	0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
| 	file_sdk_database_newdbplugin_proto_database_proto_rawDescOnce sync.Once | 	file_sdk_database_dbplugin_v5_proto_database_proto_rawDescOnce sync.Once | ||||||
| 	file_sdk_database_newdbplugin_proto_database_proto_rawDescData = file_sdk_database_newdbplugin_proto_database_proto_rawDesc | 	file_sdk_database_dbplugin_v5_proto_database_proto_rawDescData = file_sdk_database_dbplugin_v5_proto_database_proto_rawDesc | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func file_sdk_database_newdbplugin_proto_database_proto_rawDescGZIP() []byte { | func file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP() []byte { | ||||||
| 	file_sdk_database_newdbplugin_proto_database_proto_rawDescOnce.Do(func() { | 	file_sdk_database_dbplugin_v5_proto_database_proto_rawDescOnce.Do(func() { | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_rawDescData = protoimpl.X.CompressGZIP(file_sdk_database_newdbplugin_proto_database_proto_rawDescData) | 		file_sdk_database_dbplugin_v5_proto_database_proto_rawDescData = protoimpl.X.CompressGZIP(file_sdk_database_dbplugin_v5_proto_database_proto_rawDescData) | ||||||
| 	}) | 	}) | ||||||
| 	return file_sdk_database_newdbplugin_proto_database_proto_rawDescData | 	return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescData | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var file_sdk_database_newdbplugin_proto_database_proto_msgTypes = make([]protoimpl.MessageInfo, 14) | var file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes = make([]protoimpl.MessageInfo, 14) | ||||||
| var file_sdk_database_newdbplugin_proto_database_proto_goTypes = []interface{}{ | var file_sdk_database_dbplugin_v5_proto_database_proto_goTypes = []interface{}{ | ||||||
| 	(*InitializeRequest)(nil),   // 0: newdbplugin.InitializeRequest | 	(*InitializeRequest)(nil),   // 0: dbplugin.v5.InitializeRequest | ||||||
| 	(*InitializeResponse)(nil),  // 1: newdbplugin.InitializeResponse | 	(*InitializeResponse)(nil),  // 1: dbplugin.v5.InitializeResponse | ||||||
| 	(*NewUserRequest)(nil),      // 2: newdbplugin.NewUserRequest | 	(*NewUserRequest)(nil),      // 2: dbplugin.v5.NewUserRequest | ||||||
| 	(*UsernameConfig)(nil),      // 3: newdbplugin.UsernameConfig | 	(*UsernameConfig)(nil),      // 3: dbplugin.v5.UsernameConfig | ||||||
| 	(*NewUserResponse)(nil),     // 4: newdbplugin.NewUserResponse | 	(*NewUserResponse)(nil),     // 4: dbplugin.v5.NewUserResponse | ||||||
| 	(*UpdateUserRequest)(nil),   // 5: newdbplugin.UpdateUserRequest | 	(*UpdateUserRequest)(nil),   // 5: dbplugin.v5.UpdateUserRequest | ||||||
| 	(*ChangePassword)(nil),      // 6: newdbplugin.ChangePassword | 	(*ChangePassword)(nil),      // 6: dbplugin.v5.ChangePassword | ||||||
| 	(*ChangeExpiration)(nil),    // 7: newdbplugin.ChangeExpiration | 	(*ChangeExpiration)(nil),    // 7: dbplugin.v5.ChangeExpiration | ||||||
| 	(*UpdateUserResponse)(nil),  // 8: newdbplugin.UpdateUserResponse | 	(*UpdateUserResponse)(nil),  // 8: dbplugin.v5.UpdateUserResponse | ||||||
| 	(*DeleteUserRequest)(nil),   // 9: newdbplugin.DeleteUserRequest | 	(*DeleteUserRequest)(nil),   // 9: dbplugin.v5.DeleteUserRequest | ||||||
| 	(*DeleteUserResponse)(nil),  // 10: newdbplugin.DeleteUserResponse | 	(*DeleteUserResponse)(nil),  // 10: dbplugin.v5.DeleteUserResponse | ||||||
| 	(*TypeResponse)(nil),        // 11: newdbplugin.TypeResponse | 	(*TypeResponse)(nil),        // 11: dbplugin.v5.TypeResponse | ||||||
| 	(*Statements)(nil),          // 12: newdbplugin.Statements | 	(*Statements)(nil),          // 12: dbplugin.v5.Statements | ||||||
| 	(*Empty)(nil),               // 13: newdbplugin.Empty | 	(*Empty)(nil),               // 13: dbplugin.v5.Empty | ||||||
| 	(*_struct.Struct)(nil),      // 14: google.protobuf.Struct | 	(*_struct.Struct)(nil),      // 14: google.protobuf.Struct | ||||||
| 	(*timestamp.Timestamp)(nil), // 15: google.protobuf.Timestamp | 	(*timestamp.Timestamp)(nil), // 15: google.protobuf.Timestamp | ||||||
| } | } | ||||||
| var file_sdk_database_newdbplugin_proto_database_proto_depIdxs = []int32{ | var file_sdk_database_dbplugin_v5_proto_database_proto_depIdxs = []int32{ | ||||||
| 	14, // 0: newdbplugin.InitializeRequest.config_data:type_name -> google.protobuf.Struct | 	14, // 0: dbplugin.v5.InitializeRequest.config_data:type_name -> google.protobuf.Struct | ||||||
| 	14, // 1: newdbplugin.InitializeResponse.config_data:type_name -> google.protobuf.Struct | 	14, // 1: dbplugin.v5.InitializeResponse.config_data:type_name -> google.protobuf.Struct | ||||||
| 	3,  // 2: newdbplugin.NewUserRequest.username_config:type_name -> newdbplugin.UsernameConfig | 	3,  // 2: dbplugin.v5.NewUserRequest.username_config:type_name -> dbplugin.v5.UsernameConfig | ||||||
| 	15, // 3: newdbplugin.NewUserRequest.expiration:type_name -> google.protobuf.Timestamp | 	15, // 3: dbplugin.v5.NewUserRequest.expiration:type_name -> google.protobuf.Timestamp | ||||||
| 	12, // 4: newdbplugin.NewUserRequest.statements:type_name -> newdbplugin.Statements | 	12, // 4: dbplugin.v5.NewUserRequest.statements:type_name -> dbplugin.v5.Statements | ||||||
| 	12, // 5: newdbplugin.NewUserRequest.rollback_statements:type_name -> newdbplugin.Statements | 	12, // 5: dbplugin.v5.NewUserRequest.rollback_statements:type_name -> dbplugin.v5.Statements | ||||||
| 	6,  // 6: newdbplugin.UpdateUserRequest.password:type_name -> newdbplugin.ChangePassword | 	6,  // 6: dbplugin.v5.UpdateUserRequest.password:type_name -> dbplugin.v5.ChangePassword | ||||||
| 	7,  // 7: newdbplugin.UpdateUserRequest.expiration:type_name -> newdbplugin.ChangeExpiration | 	7,  // 7: dbplugin.v5.UpdateUserRequest.expiration:type_name -> dbplugin.v5.ChangeExpiration | ||||||
| 	12, // 8: newdbplugin.ChangePassword.statements:type_name -> newdbplugin.Statements | 	12, // 8: dbplugin.v5.ChangePassword.statements:type_name -> dbplugin.v5.Statements | ||||||
| 	15, // 9: newdbplugin.ChangeExpiration.new_expiration:type_name -> google.protobuf.Timestamp | 	15, // 9: dbplugin.v5.ChangeExpiration.new_expiration:type_name -> google.protobuf.Timestamp | ||||||
| 	12, // 10: newdbplugin.ChangeExpiration.statements:type_name -> newdbplugin.Statements | 	12, // 10: dbplugin.v5.ChangeExpiration.statements:type_name -> dbplugin.v5.Statements | ||||||
| 	12, // 11: newdbplugin.DeleteUserRequest.statements:type_name -> newdbplugin.Statements | 	12, // 11: dbplugin.v5.DeleteUserRequest.statements:type_name -> dbplugin.v5.Statements | ||||||
| 	0,  // 12: newdbplugin.Database.Initialize:input_type -> newdbplugin.InitializeRequest | 	0,  // 12: dbplugin.v5.Database.Initialize:input_type -> dbplugin.v5.InitializeRequest | ||||||
| 	2,  // 13: newdbplugin.Database.NewUser:input_type -> newdbplugin.NewUserRequest | 	2,  // 13: dbplugin.v5.Database.NewUser:input_type -> dbplugin.v5.NewUserRequest | ||||||
| 	5,  // 14: newdbplugin.Database.UpdateUser:input_type -> newdbplugin.UpdateUserRequest | 	5,  // 14: dbplugin.v5.Database.UpdateUser:input_type -> dbplugin.v5.UpdateUserRequest | ||||||
| 	9,  // 15: newdbplugin.Database.DeleteUser:input_type -> newdbplugin.DeleteUserRequest | 	9,  // 15: dbplugin.v5.Database.DeleteUser:input_type -> dbplugin.v5.DeleteUserRequest | ||||||
| 	13, // 16: newdbplugin.Database.Type:input_type -> newdbplugin.Empty | 	13, // 16: dbplugin.v5.Database.Type:input_type -> dbplugin.v5.Empty | ||||||
| 	13, // 17: newdbplugin.Database.Close:input_type -> newdbplugin.Empty | 	13, // 17: dbplugin.v5.Database.Close:input_type -> dbplugin.v5.Empty | ||||||
| 	1,  // 18: newdbplugin.Database.Initialize:output_type -> newdbplugin.InitializeResponse | 	1,  // 18: dbplugin.v5.Database.Initialize:output_type -> dbplugin.v5.InitializeResponse | ||||||
| 	4,  // 19: newdbplugin.Database.NewUser:output_type -> newdbplugin.NewUserResponse | 	4,  // 19: dbplugin.v5.Database.NewUser:output_type -> dbplugin.v5.NewUserResponse | ||||||
| 	8,  // 20: newdbplugin.Database.UpdateUser:output_type -> newdbplugin.UpdateUserResponse | 	8,  // 20: dbplugin.v5.Database.UpdateUser:output_type -> dbplugin.v5.UpdateUserResponse | ||||||
| 	10, // 21: newdbplugin.Database.DeleteUser:output_type -> newdbplugin.DeleteUserResponse | 	10, // 21: dbplugin.v5.Database.DeleteUser:output_type -> dbplugin.v5.DeleteUserResponse | ||||||
| 	11, // 22: newdbplugin.Database.Type:output_type -> newdbplugin.TypeResponse | 	11, // 22: dbplugin.v5.Database.Type:output_type -> dbplugin.v5.TypeResponse | ||||||
| 	13, // 23: newdbplugin.Database.Close:output_type -> newdbplugin.Empty | 	13, // 23: dbplugin.v5.Database.Close:output_type -> dbplugin.v5.Empty | ||||||
| 	18, // [18:24] is the sub-list for method output_type | 	18, // [18:24] is the sub-list for method output_type | ||||||
| 	12, // [12:18] is the sub-list for method input_type | 	12, // [12:18] is the sub-list for method input_type | ||||||
| 	12, // [12:12] is the sub-list for extension type_name | 	12, // [12:12] is the sub-list for extension type_name | ||||||
| @@ -953,13 +953,13 @@ var file_sdk_database_newdbplugin_proto_database_proto_depIdxs = []int32{ | |||||||
| 	0,  // [0:12] is the sub-list for field type_name | 	0,  // [0:12] is the sub-list for field type_name | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func init() { file_sdk_database_newdbplugin_proto_database_proto_init() } | func init() { file_sdk_database_dbplugin_v5_proto_database_proto_init() } | ||||||
| func file_sdk_database_newdbplugin_proto_database_proto_init() { | func file_sdk_database_dbplugin_v5_proto_database_proto_init() { | ||||||
| 	if File_sdk_database_newdbplugin_proto_database_proto != nil { | 	if File_sdk_database_dbplugin_v5_proto_database_proto != nil { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if !protoimpl.UnsafeEnabled { | 	if !protoimpl.UnsafeEnabled { | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*InitializeRequest); i { | 			switch v := v.(*InitializeRequest); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -971,7 +971,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*InitializeResponse); i { | 			switch v := v.(*InitializeResponse); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -983,7 +983,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*NewUserRequest); i { | 			switch v := v.(*NewUserRequest); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -995,7 +995,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*UsernameConfig); i { | 			switch v := v.(*UsernameConfig); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1007,7 +1007,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*NewUserResponse); i { | 			switch v := v.(*NewUserResponse); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1019,7 +1019,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*UpdateUserRequest); i { | 			switch v := v.(*UpdateUserRequest); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1031,7 +1031,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*ChangePassword); i { | 			switch v := v.(*ChangePassword); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1043,7 +1043,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*ChangeExpiration); i { | 			switch v := v.(*ChangeExpiration); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1055,7 +1055,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*UpdateUserResponse); i { | 			switch v := v.(*UpdateUserResponse); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1067,7 +1067,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*DeleteUserRequest); i { | 			switch v := v.(*DeleteUserRequest); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1079,7 +1079,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*DeleteUserResponse); i { | 			switch v := v.(*DeleteUserResponse); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1091,7 +1091,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*TypeResponse); i { | 			switch v := v.(*TypeResponse); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1103,7 +1103,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*Statements); i { | 			switch v := v.(*Statements); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1115,7 +1115,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 				return nil | 				return nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		file_sdk_database_newdbplugin_proto_database_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { | 		file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { | ||||||
| 			switch v := v.(*Empty); i { | 			switch v := v.(*Empty); i { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				return &v.state | 				return &v.state | ||||||
| @@ -1132,20 +1132,20 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { | |||||||
| 	out := protoimpl.TypeBuilder{ | 	out := protoimpl.TypeBuilder{ | ||||||
| 		File: protoimpl.DescBuilder{ | 		File: protoimpl.DescBuilder{ | ||||||
| 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(), | 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(), | ||||||
| 			RawDescriptor: file_sdk_database_newdbplugin_proto_database_proto_rawDesc, | 			RawDescriptor: file_sdk_database_dbplugin_v5_proto_database_proto_rawDesc, | ||||||
| 			NumEnums:      0, | 			NumEnums:      0, | ||||||
| 			NumMessages:   14, | 			NumMessages:   14, | ||||||
| 			NumExtensions: 0, | 			NumExtensions: 0, | ||||||
| 			NumServices:   1, | 			NumServices:   1, | ||||||
| 		}, | 		}, | ||||||
| 		GoTypes:           file_sdk_database_newdbplugin_proto_database_proto_goTypes, | 		GoTypes:           file_sdk_database_dbplugin_v5_proto_database_proto_goTypes, | ||||||
| 		DependencyIndexes: file_sdk_database_newdbplugin_proto_database_proto_depIdxs, | 		DependencyIndexes: file_sdk_database_dbplugin_v5_proto_database_proto_depIdxs, | ||||||
| 		MessageInfos:      file_sdk_database_newdbplugin_proto_database_proto_msgTypes, | 		MessageInfos:      file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes, | ||||||
| 	}.Build() | 	}.Build() | ||||||
| 	File_sdk_database_newdbplugin_proto_database_proto = out.File | 	File_sdk_database_dbplugin_v5_proto_database_proto = out.File | ||||||
| 	file_sdk_database_newdbplugin_proto_database_proto_rawDesc = nil | 	file_sdk_database_dbplugin_v5_proto_database_proto_rawDesc = nil | ||||||
| 	file_sdk_database_newdbplugin_proto_database_proto_goTypes = nil | 	file_sdk_database_dbplugin_v5_proto_database_proto_goTypes = nil | ||||||
| 	file_sdk_database_newdbplugin_proto_database_proto_depIdxs = nil | 	file_sdk_database_dbplugin_v5_proto_database_proto_depIdxs = nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Reference imports to suppress errors if they are not otherwise used. | // Reference imports to suppress errors if they are not otherwise used. | ||||||
| @@ -1178,7 +1178,7 @@ func NewDatabaseClient(cc grpc.ClientConnInterface) DatabaseClient { | |||||||
| 
 | 
 | ||||||
| func (c *databaseClient) Initialize(ctx context.Context, in *InitializeRequest, opts ...grpc.CallOption) (*InitializeResponse, error) { | func (c *databaseClient) Initialize(ctx context.Context, in *InitializeRequest, opts ...grpc.CallOption) (*InitializeResponse, error) { | ||||||
| 	out := new(InitializeResponse) | 	out := new(InitializeResponse) | ||||||
| 	err := c.cc.Invoke(ctx, "/newdbplugin.Database/Initialize", in, out, opts...) | 	err := c.cc.Invoke(ctx, "/dbplugin.v5.Database/Initialize", in, out, opts...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -1187,7 +1187,7 @@ func (c *databaseClient) Initialize(ctx context.Context, in *InitializeRequest, | |||||||
| 
 | 
 | ||||||
| func (c *databaseClient) NewUser(ctx context.Context, in *NewUserRequest, opts ...grpc.CallOption) (*NewUserResponse, error) { | func (c *databaseClient) NewUser(ctx context.Context, in *NewUserRequest, opts ...grpc.CallOption) (*NewUserResponse, error) { | ||||||
| 	out := new(NewUserResponse) | 	out := new(NewUserResponse) | ||||||
| 	err := c.cc.Invoke(ctx, "/newdbplugin.Database/NewUser", in, out, opts...) | 	err := c.cc.Invoke(ctx, "/dbplugin.v5.Database/NewUser", in, out, opts...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -1196,7 +1196,7 @@ func (c *databaseClient) NewUser(ctx context.Context, in *NewUserRequest, opts . | |||||||
| 
 | 
 | ||||||
| func (c *databaseClient) UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*UpdateUserResponse, error) { | func (c *databaseClient) UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*UpdateUserResponse, error) { | ||||||
| 	out := new(UpdateUserResponse) | 	out := new(UpdateUserResponse) | ||||||
| 	err := c.cc.Invoke(ctx, "/newdbplugin.Database/UpdateUser", in, out, opts...) | 	err := c.cc.Invoke(ctx, "/dbplugin.v5.Database/UpdateUser", in, out, opts...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -1205,7 +1205,7 @@ func (c *databaseClient) UpdateUser(ctx context.Context, in *UpdateUserRequest, | |||||||
| 
 | 
 | ||||||
| func (c *databaseClient) DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*DeleteUserResponse, error) { | func (c *databaseClient) DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*DeleteUserResponse, error) { | ||||||
| 	out := new(DeleteUserResponse) | 	out := new(DeleteUserResponse) | ||||||
| 	err := c.cc.Invoke(ctx, "/newdbplugin.Database/DeleteUser", in, out, opts...) | 	err := c.cc.Invoke(ctx, "/dbplugin.v5.Database/DeleteUser", in, out, opts...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -1214,7 +1214,7 @@ func (c *databaseClient) DeleteUser(ctx context.Context, in *DeleteUserRequest, | |||||||
| 
 | 
 | ||||||
| func (c *databaseClient) Type(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TypeResponse, error) { | func (c *databaseClient) Type(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TypeResponse, error) { | ||||||
| 	out := new(TypeResponse) | 	out := new(TypeResponse) | ||||||
| 	err := c.cc.Invoke(ctx, "/newdbplugin.Database/Type", in, out, opts...) | 	err := c.cc.Invoke(ctx, "/dbplugin.v5.Database/Type", in, out, opts...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -1223,7 +1223,7 @@ func (c *databaseClient) Type(ctx context.Context, in *Empty, opts ...grpc.CallO | |||||||
| 
 | 
 | ||||||
| func (c *databaseClient) Close(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { | func (c *databaseClient) Close(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { | ||||||
| 	out := new(Empty) | 	out := new(Empty) | ||||||
| 	err := c.cc.Invoke(ctx, "/newdbplugin.Database/Close", in, out, opts...) | 	err := c.cc.Invoke(ctx, "/dbplugin.v5.Database/Close", in, out, opts...) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @@ -1277,7 +1277,7 @@ func _Database_Initialize_Handler(srv interface{}, ctx context.Context, dec func | |||||||
| 	} | 	} | ||||||
| 	info := &grpc.UnaryServerInfo{ | 	info := &grpc.UnaryServerInfo{ | ||||||
| 		Server:     srv, | 		Server:     srv, | ||||||
| 		FullMethod: "/newdbplugin.Database/Initialize", | 		FullMethod: "/dbplugin.v5.Database/Initialize", | ||||||
| 	} | 	} | ||||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||||
| 		return srv.(DatabaseServer).Initialize(ctx, req.(*InitializeRequest)) | 		return srv.(DatabaseServer).Initialize(ctx, req.(*InitializeRequest)) | ||||||
| @@ -1295,7 +1295,7 @@ func _Database_NewUser_Handler(srv interface{}, ctx context.Context, dec func(in | |||||||
| 	} | 	} | ||||||
| 	info := &grpc.UnaryServerInfo{ | 	info := &grpc.UnaryServerInfo{ | ||||||
| 		Server:     srv, | 		Server:     srv, | ||||||
| 		FullMethod: "/newdbplugin.Database/NewUser", | 		FullMethod: "/dbplugin.v5.Database/NewUser", | ||||||
| 	} | 	} | ||||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||||
| 		return srv.(DatabaseServer).NewUser(ctx, req.(*NewUserRequest)) | 		return srv.(DatabaseServer).NewUser(ctx, req.(*NewUserRequest)) | ||||||
| @@ -1313,7 +1313,7 @@ func _Database_UpdateUser_Handler(srv interface{}, ctx context.Context, dec func | |||||||
| 	} | 	} | ||||||
| 	info := &grpc.UnaryServerInfo{ | 	info := &grpc.UnaryServerInfo{ | ||||||
| 		Server:     srv, | 		Server:     srv, | ||||||
| 		FullMethod: "/newdbplugin.Database/UpdateUser", | 		FullMethod: "/dbplugin.v5.Database/UpdateUser", | ||||||
| 	} | 	} | ||||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||||
| 		return srv.(DatabaseServer).UpdateUser(ctx, req.(*UpdateUserRequest)) | 		return srv.(DatabaseServer).UpdateUser(ctx, req.(*UpdateUserRequest)) | ||||||
| @@ -1331,7 +1331,7 @@ func _Database_DeleteUser_Handler(srv interface{}, ctx context.Context, dec func | |||||||
| 	} | 	} | ||||||
| 	info := &grpc.UnaryServerInfo{ | 	info := &grpc.UnaryServerInfo{ | ||||||
| 		Server:     srv, | 		Server:     srv, | ||||||
| 		FullMethod: "/newdbplugin.Database/DeleteUser", | 		FullMethod: "/dbplugin.v5.Database/DeleteUser", | ||||||
| 	} | 	} | ||||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||||
| 		return srv.(DatabaseServer).DeleteUser(ctx, req.(*DeleteUserRequest)) | 		return srv.(DatabaseServer).DeleteUser(ctx, req.(*DeleteUserRequest)) | ||||||
| @@ -1349,7 +1349,7 @@ func _Database_Type_Handler(srv interface{}, ctx context.Context, dec func(inter | |||||||
| 	} | 	} | ||||||
| 	info := &grpc.UnaryServerInfo{ | 	info := &grpc.UnaryServerInfo{ | ||||||
| 		Server:     srv, | 		Server:     srv, | ||||||
| 		FullMethod: "/newdbplugin.Database/Type", | 		FullMethod: "/dbplugin.v5.Database/Type", | ||||||
| 	} | 	} | ||||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||||
| 		return srv.(DatabaseServer).Type(ctx, req.(*Empty)) | 		return srv.(DatabaseServer).Type(ctx, req.(*Empty)) | ||||||
| @@ -1367,7 +1367,7 @@ func _Database_Close_Handler(srv interface{}, ctx context.Context, dec func(inte | |||||||
| 	} | 	} | ||||||
| 	info := &grpc.UnaryServerInfo{ | 	info := &grpc.UnaryServerInfo{ | ||||||
| 		Server:     srv, | 		Server:     srv, | ||||||
| 		FullMethod: "/newdbplugin.Database/Close", | 		FullMethod: "/dbplugin.v5.Database/Close", | ||||||
| 	} | 	} | ||||||
| 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | 	handler := func(ctx context.Context, req interface{}) (interface{}, error) { | ||||||
| 		return srv.(DatabaseServer).Close(ctx, req.(*Empty)) | 		return srv.(DatabaseServer).Close(ctx, req.(*Empty)) | ||||||
| @@ -1376,7 +1376,7 @@ func _Database_Close_Handler(srv interface{}, ctx context.Context, dec func(inte | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var _Database_serviceDesc = grpc.ServiceDesc{ | var _Database_serviceDesc = grpc.ServiceDesc{ | ||||||
| 	ServiceName: "newdbplugin.Database", | 	ServiceName: "dbplugin.v5.Database", | ||||||
| 	HandlerType: (*DatabaseServer)(nil), | 	HandlerType: (*DatabaseServer)(nil), | ||||||
| 	Methods: []grpc.MethodDesc{ | 	Methods: []grpc.MethodDesc{ | ||||||
| 		{ | 		{ | ||||||
| @@ -1405,5 +1405,5 @@ var _Database_serviceDesc = grpc.ServiceDesc{ | |||||||
| 		}, | 		}, | ||||||
| 	}, | 	}, | ||||||
| 	Streams:  []grpc.StreamDesc{}, | 	Streams:  []grpc.StreamDesc{}, | ||||||
| 	Metadata: "sdk/database/newdbplugin/proto/database.proto", | 	Metadata: "sdk/database/dbplugin/v5/proto/database.proto", | ||||||
| } | } | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| syntax = "proto3"; | syntax = "proto3"; | ||||||
| package newdbplugin; // TODO: Update name | package dbplugin.v5; | ||||||
| 
 | 
 | ||||||
| option go_package = "github.com/hashicorp/vault/sdk/database/newdbplugin/proto"; | option go_package = "github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto"; | ||||||
| 
 | 
 | ||||||
| import "google/protobuf/struct.proto"; | import "google/protobuf/struct.proto"; | ||||||
| import "google/protobuf/timestamp.proto"; | import "google/protobuf/timestamp.proto"; | ||||||
							
								
								
									
										85
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/testing/test_helpers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/testing/test_helpers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | |||||||
|  | package dbtesting | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"os" | ||||||
|  | 	"testing" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func getRequestTimeout(t *testing.T) time.Duration { | ||||||
|  | 	rawDur := os.Getenv("VAULT_TEST_DATABASE_REQUEST_TIMEOUT") | ||||||
|  | 	if rawDur == "" { | ||||||
|  | 		return 2 * time.Second | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dur, err := time.ParseDuration(rawDur) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Failed to parse custom request timeout %q: %s", rawDur, err) | ||||||
|  | 	} | ||||||
|  | 	return dur | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func AssertInitialize(t *testing.T, db dbplugin.Database, req dbplugin.InitializeRequest) dbplugin.InitializeResponse { | ||||||
|  | 	t.Helper() | ||||||
|  |  | ||||||
|  | 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | ||||||
|  | 	defer cancel() | ||||||
|  |  | ||||||
|  | 	resp, err := db.Initialize(ctx, req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Failed to initialize: %s", err) | ||||||
|  | 	} | ||||||
|  | 	return resp | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func AssertNewUser(t *testing.T, db dbplugin.Database, req dbplugin.NewUserRequest) dbplugin.NewUserResponse { | ||||||
|  | 	t.Helper() | ||||||
|  |  | ||||||
|  | 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | ||||||
|  | 	defer cancel() | ||||||
|  |  | ||||||
|  | 	resp, err := db.NewUser(ctx, req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Failed to create new user: %s", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if resp.Username == "" { | ||||||
|  | 		t.Fatalf("Missing username from NewUser response") | ||||||
|  | 	} | ||||||
|  | 	return resp | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func AssertUpdateUser(t *testing.T, db dbplugin.Database, req dbplugin.UpdateUserRequest) { | ||||||
|  | 	t.Helper() | ||||||
|  |  | ||||||
|  | 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | ||||||
|  | 	defer cancel() | ||||||
|  |  | ||||||
|  | 	_, err := db.UpdateUser(ctx, req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Failed to update user: %s", err) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func AssertDeleteUser(t *testing.T, db dbplugin.Database, req dbplugin.DeleteUserRequest) { | ||||||
|  | 	t.Helper() | ||||||
|  |  | ||||||
|  | 	ctx, cancel := context.WithTimeout(context.Background(), getRequestTimeout(t)) | ||||||
|  | 	defer cancel() | ||||||
|  |  | ||||||
|  | 	_, err := db.DeleteUser(ctx, req) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Failed to delete user %q: %s", req.Username, err) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func AssertClose(t *testing.T, db dbplugin.Database) { | ||||||
|  | 	t.Helper() | ||||||
|  | 	err := db.Close() | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Failed to close database: %s", err) | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -7,7 +7,7 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/golang/protobuf/ptypes" | 	"github.com/golang/protobuf/ptypes" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin/proto" | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
| 	"github.com/hashicorp/vault/sdk/helper/pluginutil" | 	"github.com/hashicorp/vault/sdk/helper/pluginutil" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_database_plugin.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_database_plugin.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -4,7 +4,7 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/go-plugin" | 	"github.com/hashicorp/go-plugin" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin/proto" | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
| 	"google.golang.org/grpc" | 	"google.golang.org/grpc" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -6,7 +6,7 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/golang/protobuf/ptypes" | 	"github.com/golang/protobuf/ptypes" | ||||||
| 	"github.com/hashicorp/vault/sdk/database/newdbplugin/proto" | 	"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||||||
| 	"google.golang.org/grpc/codes" | 	"google.golang.org/grpc/codes" | ||||||
| 	"google.golang.org/grpc/status" | 	"google.golang.org/grpc/status" | ||||||
| ) | ) | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							| @@ -553,12 +553,13 @@ github.com/hashicorp/vault-plugin-secrets-openldap/client | |||||||
| github.com/hashicorp/vault/api | github.com/hashicorp/vault/api | ||||||
| # github.com/hashicorp/vault/sdk v0.1.14-0.20201007132131-6a41edbf89f5 => ./sdk | # github.com/hashicorp/vault/sdk v0.1.14-0.20201007132131-6a41edbf89f5 => ./sdk | ||||||
| github.com/hashicorp/vault/sdk/database/dbplugin | github.com/hashicorp/vault/sdk/database/dbplugin | ||||||
|  | github.com/hashicorp/vault/sdk/database/dbplugin/v5 | ||||||
|  | github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto | ||||||
|  | github.com/hashicorp/vault/sdk/database/dbplugin/v5/testing | ||||||
| github.com/hashicorp/vault/sdk/database/helper/connutil | github.com/hashicorp/vault/sdk/database/helper/connutil | ||||||
| github.com/hashicorp/vault/sdk/database/helper/credsutil | github.com/hashicorp/vault/sdk/database/helper/credsutil | ||||||
| github.com/hashicorp/vault/sdk/database/helper/dbutil | github.com/hashicorp/vault/sdk/database/helper/dbutil | ||||||
| github.com/hashicorp/vault/sdk/database/newdbplugin | github.com/hashicorp/vault/sdk/database/newdbplugin | ||||||
| github.com/hashicorp/vault/sdk/database/newdbplugin/proto |  | ||||||
| github.com/hashicorp/vault/sdk/database/newdbplugin/testing |  | ||||||
| github.com/hashicorp/vault/sdk/framework | github.com/hashicorp/vault/sdk/framework | ||||||
| github.com/hashicorp/vault/sdk/helper/authmetadata | github.com/hashicorp/vault/sdk/helper/authmetadata | ||||||
| github.com/hashicorp/vault/sdk/helper/awsutil | github.com/hashicorp/vault/sdk/helper/awsutil | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Michael Golowka
					Michael Golowka