From 3b79e4086253bc6b9ded5081fb9f5075515151c4 Mon Sep 17 00:00:00 2001 From: Vishal Nayak Date: Thu, 15 Oct 2020 10:22:39 -0400 Subject: [PATCH 1/4] Use https to reach github instead of ssh (#10146) --- packages-oss.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages-oss.yml b/packages-oss.yml index b0407e9d4db6..8dfc13e68aaf 100644 --- a/packages-oss.yml +++ b/packages-oss.yml @@ -13,8 +13,8 @@ # config contains packagespec config for this repo. config: # product-repo is important to CI providers. - product-repo: git@github.com:hashicorp/vault.git - release-repo: git@github.com:hashicorp/vault-release.git + product-repo: https://github.com/hashicorp/vault.git + release-repo: https://github.com/hashicorp/vault-release.git # product-id is used by external systems to identify this product. # It can be any unique name, but a golang import path is ideal. product-id: github.com/hashicorp/vault From 17fa4e64e6fa2e4d63583522f780e5f40c7e1afe Mon Sep 17 00:00:00 2001 From: Jimmy Merritello <7191639+jmfury@users.noreply.github.com> Date: Thu, 15 Oct 2020 11:55:20 -0500 Subject: [PATCH 2/4] Update HSM version w/ waypoint (#10154) --- website/package-lock.json | 6 +++--- website/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/website/package-lock.json b/website/package-lock.json index 449a838609c8..eeafcada28c5 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -1748,9 +1748,9 @@ "integrity": "sha512-lv6XR2plm2m3+qO6VE+RYquTzOODIt3mQ/1fBT1bn7wsR0qxFiuryW4JfsF94oCGk++LkDkRt/8V742HiT+fHw==" }, "@hashicorp/react-hashi-stack-menu": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@hashicorp/react-hashi-stack-menu/-/react-hashi-stack-menu-1.0.6.tgz", - "integrity": "sha512-GKUmF6hoPal9mi/y1lVFeQcizQ9Kc1iYVcYwgqEDMi40C84na6Wd/AFYRckC4MNruCFXtuS3Fs8Sv7l5qqW4wA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@hashicorp/react-hashi-stack-menu/-/react-hashi-stack-menu-1.0.7.tgz", + "integrity": "sha512-WcPD9T2WjjuAlUmCNG3ed6zmroKC0T9LDf5ocL/IWTI5TSnqtjmlC63066v1YCPytG1B/QMkarFP9SYZUrIJrQ==", "requires": { "@hashicorp/react-inline-svg": "^1.0.2", "slugify": "1.3.4" diff --git a/website/package.json b/website/package.json index 3eb07b255b34..a471f7e1824d 100644 --- a/website/package.json +++ b/website/package.json @@ -12,7 +12,7 @@ "@hashicorp/react-docs-sidenav": "^3.2.5", "@hashicorp/react-enterprise-alert": "^2.1.0", "@hashicorp/react-global-styles": "^4.4.0", - "@hashicorp/react-hashi-stack-menu": "^1.0.6", + "@hashicorp/react-hashi-stack-menu": "^1.0.7", "@hashicorp/react-head": "^1.1.1", "@hashicorp/react-hero": "3.1.2", "@hashicorp/react-image": "^2.0.1", From 4ed4550d93f81ece0d61d74ded374187318edf9b Mon Sep 17 00:00:00 2001 From: Meggie Date: Thu, 15 Oct 2020 13:54:16 -0400 Subject: [PATCH 3/4] changelog++ --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f39e64298ab7..03c2557c7dce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,6 @@ BUG FIXES: * core: Fix resource leak in plugin API (plugin-dependent, not all plugins impacted) [[GH-9557](https://github.com/hashicorp/vault/pull/9557)] * core: Fix race involved in enabling certain features via a license change * identity: Check for timeouts in entity API [[GH-9925](https://github.com/hashicorp/vault/pull/9925)] -* replication (enterprise): Fix panic when old filter path evaluation fails * secrets/database: Fix handling of TLS options in mongodb connection strings [[GH-9519](https://github.com/hashicorp/vault/pull/9519)] * secrets/gcp: Ensure that the IAM policy version is appropriately set after a roleset's bindings have changed. [[GH-93](https://github.com/hashicorp/vault-plugin-secrets-gcp/pull/93)] @@ -228,6 +227,13 @@ BUG FIXES: * ui: Disallow max versions value of large than 9999999999999999 on kv2 secrets engine. [[GH-9242](https://github.com/hashicorp/vault/pull/9242)] * ui: Add and upgrade missing dependencies to resolve a failure with `make static-dist`. [[GH-9277](https://github.com/hashicorp/vault/pull/9371)] +## 1.4.7.1 +### October 15th, 2020 +### Enterprise Only + +BUG FIXES: +* replication (enterprise): Fix panic when old filter path evaluation fails + ## 1.4.7 ### September 24th, 2020 From a69ee0f65a28527376ab3d1cac89914a96406e30 Mon Sep 17 00:00:00 2001 From: Michael Golowka <72365+pcman312@users.noreply.github.com> Date: Thu, 15 Oct 2020 13:20:12 -0600 Subject: [PATCH 4/4] 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. --- Makefile | 2 +- builtin/logical/database/backend.go | 10 +- builtin/logical/database/mocks_test.go | 32 +- builtin/logical/database/mockv4.go | 14 +- builtin/logical/database/mockv5.go | 22 +- .../database/path_config_connection.go | 4 +- builtin/logical/database/path_creds_create.go | 10 +- builtin/logical/database/path_roles.go | 12 +- .../database/path_rotate_credentials.go | 8 +- builtin/logical/database/rollback.go | 8 +- builtin/logical/database/rollback_test.go | 10 +- builtin/logical/database/rotation.go | 12 +- builtin/logical/database/rotation_test.go | 3 +- builtin/logical/database/secret_creds.go | 16 +- builtin/logical/database/version_wrapper.go | 52 +- .../logical/database/version_wrapper_test.go | 134 ++-- .../logical/database/versioning_large_test.go | 12 +- plugins/database/cassandra/cassandra.go | 34 +- plugins/database/cassandra/cassandra_test.go | 33 +- .../database/cassandra/connection_producer.go | 31 +- .../database/influxdb/connection_producer.go | 26 +- plugins/database/influxdb/influxdb.go | 39 +- plugins/database/influxdb/influxdb_test.go | 84 ++- .../database/mongodb/connection_producer.go | 3 +- .../mongodb/connection_producer_test.go | 4 +- plugins/database/mongodb/mongodb.go | 52 +- plugins/database/mongodb/mongodb_test.go | 38 +- plugins/database/mssql/mssql.go | 48 +- plugins/database/mssql/mssql_test.go | 67 +- plugins/database/mysql/mysql.go | 47 +- plugins/database/mysql/mysql_test.go | 53 +- plugins/database/postgresql/postgresql.go | 50 +- .../database/postgresql/postgresql_test.go | 94 +-- sdk/database/dbplugin/v5/conversions_test.go | 506 +++++++++++++ sdk/database/dbplugin/v5/database.go | 178 +++++ sdk/database/dbplugin/v5/grpc_client.go | 254 +++++++ sdk/database/dbplugin/v5/grpc_client_test.go | 537 ++++++++++++++ .../dbplugin/v5/grpc_database_plugin.go | 42 ++ sdk/database/dbplugin/v5/grpc_server.go | 190 +++++ sdk/database/dbplugin/v5/grpc_server_test.go | 692 ++++++++++++++++++ sdk/database/dbplugin/v5/marshalling.go | 36 + sdk/database/dbplugin/v5/middleware.go | 274 +++++++ sdk/database/dbplugin/v5/middleware_test.go | 484 ++++++++++++ sdk/database/dbplugin/v5/plugin_client.go | 81 ++ sdk/database/dbplugin/v5/plugin_factory.go | 78 ++ sdk/database/dbplugin/v5/plugin_server.go | 42 ++ .../v5}/proto/database.pb.go | 330 ++++----- .../v5}/proto/database.proto | 4 +- .../dbplugin/v5}/testing/test_helpers.go | 12 +- sdk/database/newdbplugin/conversions_test.go | 2 +- sdk/database/newdbplugin/grpc_client.go | 2 +- sdk/database/newdbplugin/grpc_client_test.go | 2 +- .../newdbplugin/grpc_database_plugin.go | 2 +- sdk/database/newdbplugin/grpc_server.go | 2 +- sdk/database/newdbplugin/grpc_server_test.go | 2 +- .../newdbplugin/testing/test_helpers.go | 12 +- vault/plugin_catalog.go | 8 +- .../sdk/database/dbplugin/v5/database.go | 178 +++++ .../sdk/database/dbplugin/v5/grpc_client.go | 254 +++++++ .../dbplugin/v5/grpc_database_plugin.go | 42 ++ .../sdk/database/dbplugin/v5/grpc_server.go | 190 +++++ .../sdk/database/dbplugin/v5/marshalling.go | 36 + .../sdk/database/dbplugin/v5/middleware.go | 274 +++++++ .../sdk/database/dbplugin/v5/plugin_client.go | 81 ++ .../database/dbplugin/v5/plugin_factory.go | 78 ++ .../sdk/database/dbplugin/v5/plugin_server.go | 42 ++ .../v5}/proto/database.pb.go | 330 ++++----- .../v5}/proto/database.proto | 4 +- .../dbplugin/v5/testing/test_helpers.go | 85 +++ .../sdk/database/newdbplugin/grpc_client.go | 2 +- .../newdbplugin/grpc_database_plugin.go | 2 +- .../sdk/database/newdbplugin/grpc_server.go | 2 +- vendor/modules.txt | 5 +- 73 files changed, 5543 insertions(+), 898 deletions(-) create mode 100644 sdk/database/dbplugin/v5/conversions_test.go create mode 100644 sdk/database/dbplugin/v5/database.go create mode 100644 sdk/database/dbplugin/v5/grpc_client.go create mode 100644 sdk/database/dbplugin/v5/grpc_client_test.go create mode 100644 sdk/database/dbplugin/v5/grpc_database_plugin.go create mode 100644 sdk/database/dbplugin/v5/grpc_server.go create mode 100644 sdk/database/dbplugin/v5/grpc_server_test.go create mode 100644 sdk/database/dbplugin/v5/marshalling.go create mode 100644 sdk/database/dbplugin/v5/middleware.go create mode 100644 sdk/database/dbplugin/v5/middleware_test.go create mode 100644 sdk/database/dbplugin/v5/plugin_client.go create mode 100644 sdk/database/dbplugin/v5/plugin_factory.go create mode 100644 sdk/database/dbplugin/v5/plugin_server.go rename sdk/database/{newdbplugin => dbplugin/v5}/proto/database.pb.go (78%) rename sdk/database/{newdbplugin => dbplugin/v5}/proto/database.proto (93%) rename {vendor/github.com/hashicorp/vault/sdk/database/newdbplugin => sdk/database/dbplugin/v5}/testing/test_helpers.go (72%) create mode 100644 vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/database.go create mode 100644 vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_client.go create mode 100644 vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_database_plugin.go create mode 100644 vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_server.go create mode 100644 vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/marshalling.go create mode 100644 vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/middleware.go create mode 100644 vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_client.go create mode 100644 vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_factory.go create mode 100644 vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_server.go rename vendor/github.com/hashicorp/vault/sdk/database/{newdbplugin => dbplugin/v5}/proto/database.pb.go (78%) rename vendor/github.com/hashicorp/vault/sdk/database/{newdbplugin => dbplugin/v5}/proto/database.proto (93%) create mode 100644 vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/testing/test_helpers.go diff --git a/Makefile b/Makefile index 80c92b678af0..a326f618ce29 100644 --- a/Makefile +++ b/Makefile @@ -200,7 +200,7 @@ proto: 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 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:. 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 diff --git a/builtin/logical/database/backend.go b/builtin/logical/database/backend.go index 4ac4d396db60..621c38119bbe 100644 --- a/builtin/logical/database/backend.go +++ b/builtin/logical/database/backend.go @@ -11,9 +11,9 @@ import ( "github.com/hashicorp/errwrap" log "github.com/hashicorp/go-hclog" "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/newdbplugin" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/locksutil" "github.com/hashicorp/vault/sdk/helper/strutil" @@ -193,7 +193,7 @@ func (b *databaseBackend) roleAtPath(ctx context.Context, s logical.Storage, rol switch { case upgradeCh.Statements != nil: - var stmts dbplugin.Statements + var stmts v4.Statements if 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) } - initReq := newdbplugin.InitializeRequest{ + initReq := v5.InitializeRequest{ Config: config.ConnectionDetails, VerifyConnection: true, } @@ -316,7 +316,7 @@ func (b *databaseBackend) clearConnection(name string) error { func (b *databaseBackend) CloseIfShutdown(db *dbPluginInstance, err error) { // Plugin has shutdown, close it so next call can reconnect. 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 // and simply defer the unlock. Since we are attaching the instance and matching // the id in the connection map, we can safely do this. diff --git a/builtin/logical/database/mocks_test.go b/builtin/logical/database/mocks_test.go index 5eac0163417d..13eb53006142 100644 --- a/builtin/logical/database/mocks_test.go +++ b/builtin/logical/database/mocks_test.go @@ -4,35 +4,35 @@ import ( "context" "time" - "github.com/hashicorp/vault/sdk/database/dbplugin" - "github.com/hashicorp/vault/sdk/database/newdbplugin" + v4 "github.com/hashicorp/vault/sdk/database/dbplugin" + v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" "github.com/stretchr/testify/mock" ) -var _ newdbplugin.Database = &mockNewDatabase{} +var _ v5.Database = &mockNewDatabase{} type mockNewDatabase struct { 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) - 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) - 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) - 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) - return args.Get(0).(newdbplugin.DeleteUserResponse), args.Error(1) + return args.Get(0).(v5.DeleteUserResponse), args.Error(1) } func (m *mockNewDatabase) Type() (string, error) { @@ -45,23 +45,23 @@ func (m *mockNewDatabase) Close() error { return args.Error(0) } -var _ dbplugin.Database = &mockLegacyDatabase{} +var _ v4.Database = &mockLegacyDatabase{} type mockLegacyDatabase struct { 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) 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) 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) return args.Error(0) } @@ -76,7 +76,7 @@ func (m *mockLegacyDatabase) GenerateCredentials(ctx context.Context) (string, e 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) return args.String(0), args.String(1), args.Error(2) } diff --git a/builtin/logical/database/mockv4.go b/builtin/logical/database/mockv4.go index a9a7f043eda0..4f0b181683a8 100644 --- a/builtin/logical/database/mockv4.go +++ b/builtin/logical/database/mockv4.go @@ -7,7 +7,7 @@ import ( log "github.com/hashicorp/go-hclog" "github.com/hashicorp/vault/api" - "github.com/hashicorp/vault/sdk/database/dbplugin" + v4 "github.com/hashicorp/vault/sdk/database/dbplugin" ) const mockV4Type = "mockv4" @@ -17,7 +17,7 @@ type MockDatabaseV4 struct { config map[string]interface{} } -var _ dbplugin.Database = &MockDatabaseV4{} +var _ v4.Database = &MockDatabaseV4{} // New returns a new in-memory instance func NewV4() (interface{}, error) { @@ -31,7 +31,7 @@ func RunV4(apiTLSConfig *api.TLSConfig) error { return err } - dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) + v4.Serve(dbType.(v4.Database), api.VaultPluginTLSProvider(apiTLSConfig)) return nil } @@ -49,7 +49,7 @@ func (m MockDatabaseV4) Initialize(ctx context.Context, config map[string]interf 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", "statements", statements, "usernameConfig", usernameConfig, @@ -64,7 +64,7 @@ func (m MockDatabaseV4) CreateUser(ctx context.Context, statements dbplugin.Stat 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", "statements", statements, "username", username, @@ -73,7 +73,7 @@ func (m MockDatabaseV4) RenewUser(ctx context.Context, statements dbplugin.State 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", "statements", statements, "username", username) @@ -94,7 +94,7 @@ func (m MockDatabaseV4) RotateRootCredentials(ctx context.Context, statements [] 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", "statements", statements, "staticConfig", staticConfig) diff --git a/builtin/logical/database/mockv5.go b/builtin/logical/database/mockv5.go index 320e06570305..f420b4b1eb7b 100644 --- a/builtin/logical/database/mockv5.go +++ b/builtin/logical/database/mockv5.go @@ -7,7 +7,7 @@ import ( log "github.com/hashicorp/go-hclog" "github.com/hashicorp/vault/api" - "github.com/hashicorp/vault/sdk/database/newdbplugin" + v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" ) const mockV5Type = "mockv5" @@ -17,7 +17,7 @@ type MockDatabaseV5 struct { config map[string]interface{} } -var _ newdbplugin.Database = &MockDatabaseV5{} +var _ v5.Database = &MockDatabaseV5{} // New returns a new in-memory instance func New() (interface{}, error) { @@ -32,46 +32,46 @@ func RunV5(apiTLSConfig *api.TLSConfig) error { return err } - newdbplugin.Serve(dbType.(newdbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) + v5.Serve(dbType.(v5.Database), api.VaultPluginTLSProvider(apiTLSConfig)) 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", "req", req) config := req.Config config["from-plugin"] = "this value is from the plugin itself" - resp := newdbplugin.InitializeResponse{ + resp := v5.InitializeResponse{ Config: req.Config, } 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", "req", req) now := time.Now() user := fmt.Sprintf("mockv5_user_%s", now.Format(time.RFC3339)) - resp := newdbplugin.NewUserResponse{ + resp := v5.NewUserResponse{ Username: user, } 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", "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", "req", req) - return newdbplugin.DeleteUserResponse{}, nil + return v5.DeleteUserResponse{}, nil } func (m MockDatabaseV5) Type() (string, error) { diff --git a/builtin/logical/database/path_config_connection.go b/builtin/logical/database/path_config_connection.go index 75fade1e161e..377d7d288b82 100644 --- a/builtin/logical/database/path_config_connection.go +++ b/builtin/logical/database/path_config_connection.go @@ -10,7 +10,7 @@ import ( "github.com/fatih/structs" "github.com/hashicorp/errwrap" 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/logical" ) @@ -318,7 +318,7 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc { return logical.ErrorResponse("error creating database object: %s", err), nil } - initReq := newdbplugin.InitializeRequest{ + initReq := v5.InitializeRequest{ Config: config.ConnectionDetails, VerifyConnection: verifyConnection, } diff --git a/builtin/logical/database/path_creds_create.go b/builtin/logical/database/path_creds_create.go index 6688cc17d773..1422f1934b9f 100644 --- a/builtin/logical/database/path_creds_create.go +++ b/builtin/logical/database/path_creds_create.go @@ -5,7 +5,7 @@ import ( "fmt" "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/helper/strutil" "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) } - newUserReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + newUserReq := v5.NewUserRequest{ + UsernameConfig: v5.UsernameMetadata{ DisplayName: req.DisplayName, RoleName: name, }, - Statements: newdbplugin.Statements{ + Statements: v5.Statements{ Commands: role.Statements.Creation, }, - RollbackStatements: newdbplugin.Statements{ + RollbackStatements: v5.Statements{ Commands: role.Statements.Rollback, }, Password: password, diff --git a/builtin/logical/database/path_roles.go b/builtin/logical/database/path_roles.go index 70673174003a..dcaeb23432f6 100644 --- a/builtin/logical/database/path_roles.go +++ b/builtin/logical/database/path_roles.go @@ -6,7 +6,7 @@ import ( "strings" "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/helper/locksutil" "github.com/hashicorp/vault/sdk/helper/strutil" @@ -522,11 +522,11 @@ func (b *databaseBackend) pathStaticRoleCreateUpdate(ctx context.Context, req *l } type roleEntry struct { - DBName string `json:"db_name"` - Statements dbplugin.Statements `json:"statements"` - DefaultTTL time.Duration `json:"default_ttl"` - MaxTTL time.Duration `json:"max_ttl"` - StaticAccount *staticAccount `json:"static_account" mapstructure:"static_account"` + DBName string `json:"db_name"` + Statements v4.Statements `json:"statements"` + DefaultTTL time.Duration `json:"default_ttl"` + MaxTTL time.Duration `json:"max_ttl"` + StaticAccount *staticAccount `json:"static_account" mapstructure:"static_account"` } type staticAccount struct { diff --git a/builtin/logical/database/path_rotate_credentials.go b/builtin/logical/database/path_rotate_credentials.go index c1f3e102f616..55a2cf83abda 100644 --- a/builtin/logical/database/path_rotate_credentials.go +++ b/builtin/logical/database/path_rotate_credentials.go @@ -5,7 +5,7 @@ import ( "fmt" "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/logical" "github.com/hashicorp/vault/sdk/queue" @@ -111,11 +111,11 @@ func (b *databaseBackend) pathRotateRootCredentialsUpdate() framework.OperationF return nil, err } - updateReq := newdbplugin.UpdateUserRequest{ + updateReq := v5.UpdateUserRequest{ Username: username, - Password: &newdbplugin.ChangePassword{ + Password: &v5.ChangePassword{ NewPassword: newPassword, - Statements: newdbplugin.Statements{ + Statements: v5.Statements{ Commands: config.RootCredentialsRotateStatements, }, }, diff --git a/builtin/logical/database/rollback.go b/builtin/logical/database/rollback.go index 8631d7e33d28..ab261b87e16c 100644 --- a/builtin/logical/database/rollback.go +++ b/builtin/logical/database/rollback.go @@ -4,7 +4,7 @@ import ( "context" "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/mitchellh/mapstructure" "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, - Password: &newdbplugin.ChangePassword{ + Password: &v5.ChangePassword{ NewPassword: entry.OldPassword, - Statements: newdbplugin.Statements{ + Statements: v5.Statements{ Commands: config.RootCredentialsRotateStatements, }, }, diff --git a/builtin/logical/database/rollback_test.go b/builtin/logical/database/rollback_test.go index 3f41b5362ea2..48e3744cc88c 100644 --- a/builtin/logical/database/rollback_test.go +++ b/builtin/logical/database/rollback_test.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/vault/helper/namespace" 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/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 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() - updateReq := newdbplugin.UpdateUserRequest{ + updateReq := v5.UpdateUserRequest{ Username: databaseUser, - Password: &newdbplugin.ChangePassword{ + Password: &v5.ChangePassword{ NewPassword: "newSecret", }, } @@ -348,9 +348,9 @@ func TestBackend_RotateRootCredentials_WAL_no_rollback_2(t *testing.T) { // Alter the database password ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() - updateReq := newdbplugin.UpdateUserRequest{ + updateReq := v5.UpdateUserRequest{ Username: databaseUser, - Password: &newdbplugin.ChangePassword{ + Password: &v5.ChangePassword{ NewPassword: "newSecret", }, } diff --git a/builtin/logical/database/rotation.go b/builtin/logical/database/rotation.go index 0194fb49052d..3bd8ebfff4b9 100644 --- a/builtin/logical/database/rotation.go +++ b/builtin/logical/database/rotation.go @@ -9,8 +9,8 @@ import ( "github.com/hashicorp/errwrap" "github.com/hashicorp/go-multierror" - "github.com/hashicorp/vault/sdk/database/dbplugin" - "github.com/hashicorp/vault/sdk/database/newdbplugin" + v4 "github.com/hashicorp/vault/sdk/database/dbplugin" + v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/consts" "github.com/hashicorp/vault/sdk/helper/locksutil" @@ -340,7 +340,7 @@ func (b *databaseBackend) setStaticAccount(ctx context.Context, s logical.Storag } output.Password = newPassword - config := dbplugin.StaticUserConfig{ + config := v4.StaticUserConfig{ Username: input.Role.StaticAccount.Username, 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, - Password: &newdbplugin.ChangePassword{ + Password: &v5.ChangePassword{ NewPassword: newPassword, - Statements: newdbplugin.Statements{ + Statements: v5.Statements{ Commands: input.Role.Statements.Rotation, }, }, diff --git a/builtin/logical/database/rotation_test.go b/builtin/logical/database/rotation_test.go index a8ac0fb05374..28314c8fe2b0 100644 --- a/builtin/logical/database/rotation_test.go +++ b/builtin/logical/database/rotation_test.go @@ -2,14 +2,13 @@ package database import ( "context" + "database/sql" "log" "os" "strings" "testing" "time" - "database/sql" - "github.com/Sectorbob/mlab-ns2/gae/ns/digest" "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/helper/testhelpers/mongodb" diff --git a/builtin/logical/database/secret_creds.go b/builtin/logical/database/secret_creds.go index 56609e2b6158..9c9b348e2437 100644 --- a/builtin/logical/database/secret_creds.go +++ b/builtin/logical/database/secret_creds.go @@ -5,8 +5,8 @@ import ( "fmt" "time" - "github.com/hashicorp/vault/sdk/database/dbplugin" - "github.com/hashicorp/vault/sdk/database/newdbplugin" + v4 "github.com/hashicorp/vault/sdk/database/dbplugin" + v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" "github.com/hashicorp/vault/sdk/framework" "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 expireTime = expireTime.Add(5 * time.Second) - updateReq := newdbplugin.UpdateUserRequest{ + updateReq := v5.UpdateUserRequest{ Username: username, - Expiration: &newdbplugin.ChangeExpiration{ + Expiration: &v5.ChangeExpiration{ NewExpiration: expireTime, - Statements: newdbplugin.Statements{ + Statements: v5.Statements{ Commands: role.Statements.Renewal, }, }, @@ -104,7 +104,7 @@ func (b *databaseBackend) secretCredsRevoke() framework.OperationFunc { } var dbName string - var statements dbplugin.Statements + var statements v4.Statements role, err := b.Role(ctx, req.Storage, roleNameRaw.(string)) if err != nil { @@ -148,9 +148,9 @@ func (b *databaseBackend) secretCredsRevoke() framework.OperationFunc { dbi.RLock() defer dbi.RUnlock() - deleteReq := newdbplugin.DeleteUserRequest{ + deleteReq := v5.DeleteUserRequest{ Username: username, - Statements: newdbplugin.Statements{ + Statements: v5.Statements{ Commands: statements.Revocation, }, } diff --git a/builtin/logical/database/version_wrapper.go b/builtin/logical/database/version_wrapper.go index f79f1aff257f..a2341a89a206 100644 --- a/builtin/logical/database/version_wrapper.go +++ b/builtin/logical/database/version_wrapper.go @@ -8,22 +8,22 @@ import ( log "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-multierror" "github.com/hashicorp/vault/helper/random" - "github.com/hashicorp/vault/sdk/database/dbplugin" - "github.com/hashicorp/vault/sdk/database/newdbplugin" + v4 "github.com/hashicorp/vault/sdk/database/dbplugin" + v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" "github.com/hashicorp/vault/sdk/helper/pluginutil" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) type databaseVersionWrapper struct { - v4 dbplugin.Database - v5 newdbplugin.Database + v4 v4.Database + v5 v5.Database } // 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. 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 { dbw = databaseVersionWrapper{ v5: newDB, @@ -34,7 +34,7 @@ func newDatabaseWrapper(ctx context.Context, pluginName string, sys pluginutil.L merr := &multierror.Error{} merr = multierror.Append(merr, err) - legacyDB, err := dbplugin.PluginFactory(ctx, pluginName, sys, logger) + legacyDB, err := v4.PluginFactory(ctx, pluginName, sys, logger) if err == nil { dbw = databaseVersionWrapper{ 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. // 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() { - return newdbplugin.InitializeResponse{}, fmt.Errorf("no underlying database specified") + return v5.InitializeResponse{}, fmt.Errorf("no underlying database specified") } // v5 Database @@ -61,9 +61,9 @@ func (d databaseVersionWrapper) Initialize(ctx context.Context, req newdbplugin. // v4 Database saveConfig, err := d.v4.Init(ctx, req.Config, req.VerifyConnection) if err != nil { - return newdbplugin.InitializeResponse{}, err + return v5.InitializeResponse{}, err } - resp := newdbplugin.InitializeResponse{ + resp := v5.InitializeResponse{ Config: saveConfig, } 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. // 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. -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() { - return newdbplugin.NewUserResponse{}, "", fmt.Errorf("no underlying database specified") + return v5.NewUserResponse{}, "", fmt.Errorf("no underlying database specified") } // v5 Database @@ -86,11 +86,11 @@ func (d databaseVersionWrapper) NewUser(ctx context.Context, req newdbplugin.New } // v4 Database - stmts := dbplugin.Statements{ + stmts := v4.Statements{ Creation: req.Statements.Commands, Rollback: req.RollbackStatements.Commands, } - usernameConfig := dbplugin.UsernameConfig{ + usernameConfig := v4.UsernameConfig{ DisplayName: req.UsernameConfig.DisplayName, RoleName: req.UsernameConfig.RoleName, } @@ -99,7 +99,7 @@ func (d databaseVersionWrapper) NewUser(ctx context.Context, req newdbplugin.New return resp, "", err } - resp = newdbplugin.NewUserResponse{ + resp = v5.NewUserResponse{ Username: username, } 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 // in the UpdateUserRequest such as password credentials or user TTL. // 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() { return nil, fmt.Errorf("no underlying database specified") } @@ -136,7 +136,7 @@ func (d databaseVersionWrapper) UpdateUser(ctx context.Context, req newdbplugin. // Change expiration date if req.Expiration != nil { - stmts := dbplugin.Statements{ + stmts := v4.Statements{ Renewal: req.Expiration.Statements.Commands, } 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 // 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. -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) // 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 } -func (d databaseVersionWrapper) changeUserPasswordLegacy(ctx context.Context, username string, passwordChange *newdbplugin.ChangePassword) (err error) { - stmts := dbplugin.Statements{ +func (d databaseVersionWrapper) changeUserPasswordLegacy(ctx context.Context, username string, passwordChange *v5.ChangePassword) (err error) { + stmts := v4.Statements{ Rotation: passwordChange.Statements.Commands, } - staticConfig := dbplugin.StaticUserConfig{ + staticConfig := v4.StaticUserConfig{ Username: username, Password: passwordChange.NewPassword, } @@ -177,14 +177,14 @@ func (d databaseVersionWrapper) changeUserPasswordLegacy(ctx context.Context, us 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) } // 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() { - return newdbplugin.DeleteUserResponse{}, fmt.Errorf("no underlying database specified") + return v5.DeleteUserResponse{}, fmt.Errorf("no underlying database specified") } // v5 Database @@ -193,11 +193,11 @@ func (d databaseVersionWrapper) DeleteUser(ctx context.Context, req newdbplugin. } // v4 Database - stmts := dbplugin.Statements{ + stmts := v4.Statements{ Revocation: req.Statements.Commands, } 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. diff --git a/builtin/logical/database/version_wrapper_test.go b/builtin/logical/database/version_wrapper_test.go index 63cc6cb11918..e0e4cbae8b9b 100644 --- a/builtin/logical/database/version_wrapper_test.go +++ b/builtin/logical/database/version_wrapper_test.go @@ -8,7 +8,7 @@ import ( "testing" "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/stretchr/testify/mock" "google.golang.org/grpc/codes" @@ -18,13 +18,13 @@ import ( func TestInitDatabase_missingDB(t *testing.T) { dbw := databaseVersionWrapper{} - req := newdbplugin.InitializeRequest{} + req := v5.InitializeRequest{} resp, err := dbw.Initialize(context.Background(), req) if err == nil { t.Fatalf("err expected, got nil") } - expectedResp := newdbplugin.InitializeResponse{} + expectedResp := v5.InitializeResponse{} if !reflect.DeepEqual(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) { type testCase struct { - req newdbplugin.InitializeRequest + req v5.InitializeRequest - newInitResp newdbplugin.InitializeResponse + newInitResp v5.InitializeResponse newInitErr error newInitCalls int - expectedResp newdbplugin.InitializeResponse + expectedResp v5.InitializeResponse expectErr bool } tests := map[string]testCase{ "success": { - req: newdbplugin.InitializeRequest{ + req: v5.InitializeRequest{ Config: map[string]interface{}{ "foo": "bar", }, VerifyConnection: true, }, - newInitResp: newdbplugin.InitializeResponse{ + newInitResp: v5.InitializeResponse{ Config: map[string]interface{}{ "foo": "bar", }, }, newInitCalls: 1, - expectedResp: newdbplugin.InitializeResponse{ + expectedResp: v5.InitializeResponse{ Config: map[string]interface{}{ "foo": "bar", }, @@ -64,16 +64,16 @@ func TestInitDatabase_newDB(t *testing.T) { expectErr: false, }, "error": { - req: newdbplugin.InitializeRequest{ + req: v5.InitializeRequest{ Config: map[string]interface{}{ "foo": "bar", }, VerifyConnection: true, }, - newInitResp: newdbplugin.InitializeResponse{}, + newInitResp: v5.InitializeResponse{}, newInitErr: fmt.Errorf("test error"), newInitCalls: 1, - expectedResp: newdbplugin.InitializeResponse{}, + expectedResp: v5.InitializeResponse{}, expectErr: true, }, } @@ -106,19 +106,19 @@ func TestInitDatabase_newDB(t *testing.T) { func TestInitDatabase_legacyDB(t *testing.T) { type testCase struct { - req newdbplugin.InitializeRequest + req v5.InitializeRequest initConfig map[string]interface{} initErr error initCalls int - expectedResp newdbplugin.InitializeResponse + expectedResp v5.InitializeResponse expectErr bool } tests := map[string]testCase{ "success": { - req: newdbplugin.InitializeRequest{ + req: v5.InitializeRequest{ Config: map[string]interface{}{ "foo": "bar", }, @@ -128,7 +128,7 @@ func TestInitDatabase_legacyDB(t *testing.T) { "foo": "bar", }, initCalls: 1, - expectedResp: newdbplugin.InitializeResponse{ + expectedResp: v5.InitializeResponse{ Config: map[string]interface{}{ "foo": "bar", }, @@ -136,7 +136,7 @@ func TestInitDatabase_legacyDB(t *testing.T) { expectErr: false, }, "error": { - req: newdbplugin.InitializeRequest{ + req: v5.InitializeRequest{ Config: map[string]interface{}{ "foo": "bar", }, @@ -144,7 +144,7 @@ func TestInitDatabase_legacyDB(t *testing.T) { }, initErr: fmt.Errorf("test error"), initCalls: 1, - expectedResp: newdbplugin.InitializeResponse{}, + expectedResp: v5.InitializeResponse{}, expectErr: true, }, } @@ -348,13 +348,13 @@ func TestGeneratePassword_no_policy(t *testing.T) { func TestNewUser_missingDB(t *testing.T) { dbw := databaseVersionWrapper{} - req := newdbplugin.NewUserRequest{} + req := v5.NewUserRequest{} resp, pass, err := dbw.NewUser(context.Background(), req) if err == nil { t.Fatalf("err expected, got nil") } - expectedResp := newdbplugin.NewUserResponse{} + expectedResp := v5.NewUserResponse{} if !reflect.DeepEqual(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) { type testCase struct { - req newdbplugin.NewUserRequest + req v5.NewUserRequest - newUserResp newdbplugin.NewUserResponse + newUserResp v5.NewUserResponse newUserErr error newUserCalls int - expectedResp newdbplugin.NewUserResponse + expectedResp v5.NewUserResponse expectErr bool } tests := map[string]testCase{ "success": { - req: newdbplugin.NewUserRequest{ + req: v5.NewUserRequest{ Password: "new_password", }, - newUserResp: newdbplugin.NewUserResponse{ + newUserResp: v5.NewUserResponse{ Username: "newuser", }, newUserCalls: 1, - expectedResp: newdbplugin.NewUserResponse{ + expectedResp: v5.NewUserResponse{ Username: "newuser", }, expectErr: false, }, "error": { - req: newdbplugin.NewUserRequest{ + req: v5.NewUserRequest{ Password: "new_password", }, newUserErr: fmt.Errorf("test error"), newUserCalls: 1, - expectedResp: newdbplugin.NewUserResponse{}, + expectedResp: v5.NewUserResponse{}, expectErr: true, }, } @@ -437,21 +437,21 @@ func TestNewUser_newDB(t *testing.T) { func TestNewUser_legacyDB(t *testing.T) { type testCase struct { - req newdbplugin.NewUserRequest + req v5.NewUserRequest createUserUsername string createUserPassword string createUserErr error createUserCalls int - expectedResp newdbplugin.NewUserResponse + expectedResp v5.NewUserResponse expectedPassword string expectErr bool } tests := map[string]testCase{ "success": { - req: newdbplugin.NewUserRequest{ + req: v5.NewUserRequest{ Password: "new_password", }, @@ -459,21 +459,21 @@ func TestNewUser_legacyDB(t *testing.T) { createUserPassword: "securepassword", createUserCalls: 1, - expectedResp: newdbplugin.NewUserResponse{ + expectedResp: v5.NewUserResponse{ Username: "newuser", }, expectedPassword: "securepassword", expectErr: false, }, "error": { - req: newdbplugin.NewUserRequest{ + req: v5.NewUserRequest{ Password: "new_password", }, createUserErr: fmt.Errorf("test error"), createUserCalls: 1, - expectedResp: newdbplugin.NewUserResponse{}, + expectedResp: v5.NewUserResponse{}, expectErr: true, }, } @@ -511,7 +511,7 @@ func TestNewUser_legacyDB(t *testing.T) { func TestUpdateUser_missingDB(t *testing.T) { dbw := databaseVersionWrapper{} - req := newdbplugin.UpdateUserRequest{} + req := v5.UpdateUserRequest{} resp, err := dbw.UpdateUser(context.Background(), req, false) if err == nil { t.Fatalf("err expected, got nil") @@ -525,25 +525,25 @@ func TestUpdateUser_missingDB(t *testing.T) { func TestUpdateUser_newDB(t *testing.T) { type testCase struct { - req newdbplugin.UpdateUserRequest + req v5.UpdateUserRequest updateUserErr error updateUserCalls int - expectedResp newdbplugin.UpdateUserResponse + expectedResp v5.UpdateUserResponse expectErr bool } tests := map[string]testCase{ "success": { - req: newdbplugin.UpdateUserRequest{ + req: v5.UpdateUserRequest{ Username: "existing_user", }, updateUserCalls: 1, expectErr: false, }, "error": { - req: newdbplugin.UpdateUserRequest{ + req: v5.UpdateUserRequest{ Username: "existing_user", }, updateUserErr: fmt.Errorf("test error"), @@ -556,7 +556,7 @@ func TestUpdateUser_newDB(t *testing.T) { t.Run(name, func(t *testing.T) { newDB := new(mockNewDatabase) newDB.On("UpdateUser", mock.Anything, mock.Anything). - Return(newdbplugin.UpdateUserResponse{}, test.updateUserErr) + Return(v5.UpdateUserResponse{}, test.updateUserErr) defer newDB.AssertNumberOfCalls(t, "UpdateUser", test.updateUserCalls) dbw := databaseVersionWrapper{ @@ -576,7 +576,7 @@ func TestUpdateUser_newDB(t *testing.T) { func TestUpdateUser_legacyDB(t *testing.T) { type testCase struct { - req newdbplugin.UpdateUserRequest + req v5.UpdateUserRequest isRootUser bool setCredentialsErr error @@ -595,7 +595,7 @@ func TestUpdateUser_legacyDB(t *testing.T) { tests := map[string]testCase{ "missing changes": { - req: newdbplugin.UpdateUserRequest{ + req: v5.UpdateUserRequest{ Username: "existing_user", }, isRootUser: false, @@ -607,10 +607,10 @@ func TestUpdateUser_legacyDB(t *testing.T) { expectErr: true, }, "both password and expiration changes": { - req: newdbplugin.UpdateUserRequest{ + req: v5.UpdateUserRequest{ Username: "existing_user", - Password: &newdbplugin.ChangePassword{}, - Expiration: &newdbplugin.ChangeExpiration{}, + Password: &v5.ChangePassword{}, + Expiration: &v5.ChangeExpiration{}, }, isRootUser: false, @@ -621,9 +621,9 @@ func TestUpdateUser_legacyDB(t *testing.T) { expectErr: true, }, "change password - SetCredentials": { - req: newdbplugin.UpdateUserRequest{ + req: v5.UpdateUserRequest{ Username: "existing_user", - Password: &newdbplugin.ChangePassword{ + Password: &v5.ChangePassword{ NewPassword: "newpassowrd", }, }, @@ -638,9 +638,9 @@ func TestUpdateUser_legacyDB(t *testing.T) { expectErr: false, }, "change password - SetCredentials failed": { - req: newdbplugin.UpdateUserRequest{ + req: v5.UpdateUserRequest{ Username: "existing_user", - Password: &newdbplugin.ChangePassword{ + Password: &v5.ChangePassword{ NewPassword: "newpassowrd", }, }, @@ -655,9 +655,9 @@ func TestUpdateUser_legacyDB(t *testing.T) { expectErr: true, }, "change password - SetCredentials unimplemented but not a root user": { - req: newdbplugin.UpdateUserRequest{ + req: v5.UpdateUserRequest{ Username: "existing_user", - Password: &newdbplugin.ChangePassword{ + Password: &v5.ChangePassword{ NewPassword: "newpassowrd", }, }, @@ -673,9 +673,9 @@ func TestUpdateUser_legacyDB(t *testing.T) { expectErr: true, }, "change password - RotateRootCredentials": { - req: newdbplugin.UpdateUserRequest{ + req: v5.UpdateUserRequest{ Username: "existing_user", - Password: &newdbplugin.ChangePassword{ + Password: &v5.ChangePassword{ NewPassword: "newpassowrd", }, }, @@ -697,9 +697,9 @@ func TestUpdateUser_legacyDB(t *testing.T) { expectErr: false, }, "change password - RotateRootCredentials failed": { - req: newdbplugin.UpdateUserRequest{ + req: v5.UpdateUserRequest{ Username: "existing_user", - Password: &newdbplugin.ChangePassword{ + Password: &v5.ChangePassword{ NewPassword: "newpassowrd", }, }, @@ -717,9 +717,9 @@ func TestUpdateUser_legacyDB(t *testing.T) { }, "change expiration": { - req: newdbplugin.UpdateUserRequest{ + req: v5.UpdateUserRequest{ Username: "existing_user", - Expiration: &newdbplugin.ChangeExpiration{ + Expiration: &v5.ChangeExpiration{ NewExpiration: time.Now(), }, }, @@ -735,9 +735,9 @@ func TestUpdateUser_legacyDB(t *testing.T) { expectErr: false, }, "change expiration failed": { - req: newdbplugin.UpdateUserRequest{ + req: v5.UpdateUserRequest{ Username: "existing_user", - Expiration: &newdbplugin.ChangeExpiration{ + Expiration: &v5.ChangeExpiration{ NewExpiration: time.Now(), }, }, @@ -791,7 +791,7 @@ func TestUpdateUser_legacyDB(t *testing.T) { func TestDeleteUser_missingDB(t *testing.T) { dbw := databaseVersionWrapper{} - req := newdbplugin.DeleteUserRequest{} + req := v5.DeleteUserRequest{} _, err := dbw.DeleteUser(context.Background(), req) if err == nil { t.Fatalf("err expected, got nil") @@ -800,7 +800,7 @@ func TestDeleteUser_missingDB(t *testing.T) { func TestDeleteUser_newDB(t *testing.T) { type testCase struct { - req newdbplugin.DeleteUserRequest + req v5.DeleteUserRequest deleteUserErr error deleteUserCalls int @@ -810,7 +810,7 @@ func TestDeleteUser_newDB(t *testing.T) { tests := map[string]testCase{ "success": { - req: newdbplugin.DeleteUserRequest{ + req: v5.DeleteUserRequest{ Username: "existing_user", }, @@ -820,7 +820,7 @@ func TestDeleteUser_newDB(t *testing.T) { expectErr: false, }, "error": { - req: newdbplugin.DeleteUserRequest{ + req: v5.DeleteUserRequest{ Username: "existing_user", }, @@ -835,7 +835,7 @@ func TestDeleteUser_newDB(t *testing.T) { t.Run(name, func(t *testing.T) { newDB := new(mockNewDatabase) newDB.On("DeleteUser", mock.Anything, mock.Anything). - Return(newdbplugin.DeleteUserResponse{}, test.deleteUserErr) + Return(v5.DeleteUserResponse{}, test.deleteUserErr) defer newDB.AssertNumberOfCalls(t, "DeleteUser", test.deleteUserCalls) dbw := databaseVersionWrapper{ @@ -855,7 +855,7 @@ func TestDeleteUser_newDB(t *testing.T) { func TestDeleteUser_legacyDB(t *testing.T) { type testCase struct { - req newdbplugin.DeleteUserRequest + req v5.DeleteUserRequest revokeUserErr error revokeUserCalls int @@ -865,7 +865,7 @@ func TestDeleteUser_legacyDB(t *testing.T) { tests := map[string]testCase{ "success": { - req: newdbplugin.DeleteUserRequest{ + req: v5.DeleteUserRequest{ Username: "existing_user", }, @@ -875,7 +875,7 @@ func TestDeleteUser_legacyDB(t *testing.T) { expectErr: false, }, "error": { - req: newdbplugin.DeleteUserRequest{ + req: v5.DeleteUserRequest{ Username: "existing_user", }, diff --git a/builtin/logical/database/versioning_large_test.go b/builtin/logical/database/versioning_large_test.go index 7bbe04085065..4b66250ea1f9 100644 --- a/builtin/logical/database/versioning_large_test.go +++ b/builtin/logical/database/versioning_large_test.go @@ -92,7 +92,7 @@ func TestPlugin_lifecycle(t *testing.T) { Storage: config.StorageView, Data: test.configData, } - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() resp, err := b.HandleRequest(ctx, req) @@ -113,7 +113,7 @@ func TestPlugin_lifecycle(t *testing.T) { Path: fmt.Sprintf("rotate-root/%s", test.dbName), Storage: config.StorageView, } - ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second) + ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) defer cancel() resp, err = b.HandleRequest(ctx, req) @@ -136,7 +136,7 @@ func TestPlugin_lifecycle(t *testing.T) { "max_ttl": "1m", }, } - ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second) + ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) defer cancel() resp, err = b.HandleRequest(ctx, req) @@ -156,7 +156,7 @@ func TestPlugin_lifecycle(t *testing.T) { Path: fmt.Sprintf("creds/%s", dynamicRoleName), Storage: config.StorageView, } - ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second) + ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) defer cancel() resp, err = b.HandleRequest(ctx, req) @@ -182,7 +182,7 @@ func TestPlugin_lifecycle(t *testing.T) { "rotation_period": "5", }, } - ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second) + ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) defer cancel() resp, err = b.HandleRequest(ctx, req) @@ -202,7 +202,7 @@ func TestPlugin_lifecycle(t *testing.T) { Path: fmt.Sprintf("static-creds/%s", staticRoleName), Storage: config.StorageView, } - ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second) + ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) defer cancel() resp, err = b.HandleRequest(ctx, req) diff --git a/plugins/database/cassandra/cassandra.go b/plugins/database/cassandra/cassandra.go index 203b67528e80..8aabca0468af 100644 --- a/plugins/database/cassandra/cassandra.go +++ b/plugins/database/cassandra/cassandra.go @@ -8,9 +8,9 @@ import ( "github.com/gocql/gocql" multierror "github.com/hashicorp/go-multierror" "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/newdbplugin" "github.com/hashicorp/vault/sdk/helper/strutil" ) @@ -21,7 +21,7 @@ const ( cassandraTypeName = "cassandra" ) -var _ newdbplugin.Database = &Cassandra{} +var _ dbplugin.Database = &Cassandra{} // Cassandra is an implementation of Database interface type Cassandra struct { @@ -31,7 +31,7 @@ type Cassandra struct { // New returns a new Cassandra instance func New() (interface{}, error) { db := new() - dbType := newdbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) + dbType := dbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) return dbType, nil } @@ -52,7 +52,7 @@ func Run(apiTLSConfig *api.TLSConfig) error { return err } - newdbplugin.Serve(dbType.(newdbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) + dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) 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 // 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() defer c.Unlock() session, err := c.getConnection(ctx) if err != nil { - return newdbplugin.NewUserResponse{}, err + return dbplugin.NewUserResponse{}, err } creationCQL := req.Statements.Commands @@ -100,7 +100,7 @@ func (c *Cassandra) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) credsutil.ToLower(), ) if err != nil { - return newdbplugin.NewUserResponse{}, err + return dbplugin.NewUserResponse{}, err } username = strings.ReplaceAll(username, "-", "_") @@ -124,12 +124,12 @@ func (c *Cassandra) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) if rollbackErr != nil { err = multierror.Append(err, rollbackErr) } - return newdbplugin.NewUserResponse{}, err + return dbplugin.NewUserResponse{}, err } } } - resp := newdbplugin.NewUserResponse{ + resp := dbplugin.NewUserResponse{ Username: username, } return resp, nil @@ -158,20 +158,20 @@ func rollbackUser(ctx context.Context, session *gocql.Session, username string, 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 { - return newdbplugin.UpdateUserResponse{}, fmt.Errorf("no changes requested") + return dbplugin.UpdateUserResponse{}, fmt.Errorf("no changes requested") } if req.Password != nil { err := c.changeUserPassword(ctx, req.Username, req.Password) - return newdbplugin.UpdateUserResponse{}, err + return dbplugin.UpdateUserResponse{}, err } // 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) if err != nil { return err @@ -206,13 +206,13 @@ func (c *Cassandra) changeUserPassword(ctx context.Context, username string, cha } // 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() defer c.Unlock() session, err := c.getConnection(ctx) if err != nil { - return newdbplugin.DeleteUserResponse{}, err + return dbplugin.DeleteUserResponse{}, err } 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() } diff --git a/plugins/database/cassandra/cassandra_test.go b/plugins/database/cassandra/cassandra_test.go index 91bda02495c0..a80cf90eecc6 100644 --- a/plugins/database/cassandra/cassandra_test.go +++ b/plugins/database/cassandra/cassandra_test.go @@ -7,12 +7,11 @@ import ( "testing" "time" - dbtesting "github.com/hashicorp/vault/sdk/database/newdbplugin/testing" - backoff "github.com/cenkalti/backoff/v3" "github.com/gocql/gocql" "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()) { @@ -20,7 +19,7 @@ func getCassandra(t *testing.T, protocolVersion interface{}) (*Cassandra, func() pieces := strings.Split(connURL, ":") db := new() - initReq := newdbplugin.InitializeRequest{ + initReq := dbplugin.InitializeRequest{ Config: map[string]interface{}{ "hosts": connURL, "port": pieces[1], @@ -70,12 +69,12 @@ func TestCassandra_CreateUser(t *testing.T) { defer cleanup() password := "myreallysecurepassword" - createReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + createReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{createUserStatements}, }, Password: password, @@ -98,12 +97,12 @@ func TestMyCassandra_UpdateUserPassword(t *testing.T) { defer cleanup() password := "myreallysecurepassword" - createReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + createReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{createUserStatements}, }, Password: password, @@ -115,11 +114,11 @@ func TestMyCassandra_UpdateUserPassword(t *testing.T) { assertCreds(t, db.Hosts, db.Port, createResp.Username, password, 5*time.Second) newPassword := "somenewpassword" - updateReq := newdbplugin.UpdateUserRequest{ + updateReq := dbplugin.UpdateUserRequest{ Username: createResp.Username, - Password: &newdbplugin.ChangePassword{ + Password: &dbplugin.ChangePassword{ NewPassword: newPassword, - Statements: newdbplugin.Statements{}, + Statements: dbplugin.Statements{}, }, Expiration: nil, } @@ -134,12 +133,12 @@ func TestCassandra_DeleteUser(t *testing.T) { defer cleanup() password := "myreallysecurepassword" - createReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + createReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{createUserStatements}, }, Password: password, @@ -150,7 +149,7 @@ func TestCassandra_DeleteUser(t *testing.T) { assertCreds(t, db.Hosts, db.Port, createResp.Username, password, 5*time.Second) - deleteReq := newdbplugin.DeleteUserRequest{ + deleteReq := dbplugin.DeleteUserRequest{ Username: createResp.Username, } diff --git a/plugins/database/cassandra/connection_producer.go b/plugins/database/cassandra/connection_producer.go index b87622997c52..02d237d6fcd3 100644 --- a/plugins/database/cassandra/connection_producer.go +++ b/plugins/database/cassandra/connection_producer.go @@ -8,16 +8,15 @@ import ( "sync" "time" - "github.com/mitchellh/mapstructure" - "github.com/gocql/gocql" "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/dbutil" - "github.com/hashicorp/vault/sdk/database/newdbplugin" "github.com/hashicorp/vault/sdk/helper/certutil" "github.com/hashicorp/vault/sdk/helper/parseutil" "github.com/hashicorp/vault/sdk/helper/tlsutil" + "github.com/mitchellh/mapstructure" ) // cassandraConnectionProducer implements ConnectionProducer and provides an @@ -52,7 +51,7 @@ type cassandraConnectionProducer struct { 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() defer c.Unlock() @@ -60,7 +59,7 @@ func (c *cassandraConnectionProducer) Initialize(ctx context.Context, req newdbp err := mapstructure.WeakDecode(req.Config, c) if err != nil { - return newdbplugin.InitializeResponse{}, err + return dbplugin.InitializeResponse{}, err } if c.ConnectTimeoutRaw == nil { @@ -68,7 +67,7 @@ func (c *cassandraConnectionProducer) Initialize(ctx context.Context, req newdbp } c.connectTimeout, err = parseutil.ParseDurationSecond(c.ConnectTimeoutRaw) 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 { @@ -76,16 +75,16 @@ func (c *cassandraConnectionProducer) Initialize(ctx context.Context, req newdbp } c.socketKeepAlive, err = parseutil.ParseDurationSecond(c.SocketKeepAliveRaw) 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 { 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: - return newdbplugin.InitializeResponse{}, fmt.Errorf("username cannot be empty") + return dbplugin.InitializeResponse{}, fmt.Errorf("username cannot be empty") 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 @@ -94,11 +93,11 @@ func (c *cassandraConnectionProducer) Initialize(ctx context.Context, req newdbp case len(c.PemJSON) != 0: parsedCertBundle, err = certutil.ParsePKIJSON([]byte(c.PemJSON)) 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() 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.privateKey = certBundle.PrivateKey @@ -108,11 +107,11 @@ func (c *cassandraConnectionProducer) Initialize(ctx context.Context, req newdbp case len(c.PemBundle) != 0: parsedCertBundle, err = certutil.ParsePEMBundle(c.PemBundle) 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() 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.privateKey = certBundle.PrivateKey @@ -126,11 +125,11 @@ func (c *cassandraConnectionProducer) Initialize(ctx context.Context, req newdbp if req.VerifyConnection { 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, } diff --git a/plugins/database/influxdb/connection_producer.go b/plugins/database/influxdb/connection_producer.go index d2f725c04490..a3c26ca7ae42 100644 --- a/plugins/database/influxdb/connection_producer.go +++ b/plugins/database/influxdb/connection_producer.go @@ -8,8 +8,8 @@ import ( "time" "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/newdbplugin" "github.com/hashicorp/vault/sdk/helper/certutil" "github.com/hashicorp/vault/sdk/helper/parseutil" "github.com/hashicorp/vault/sdk/helper/tlsutil" @@ -43,7 +43,7 @@ type influxdbConnectionProducer struct { 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() defer i.Unlock() @@ -51,7 +51,7 @@ func (i *influxdbConnectionProducer) Initialize(ctx context.Context, req newdbpl err := mapstructure.WeakDecode(req.Config, i) if err != nil { - return newdbplugin.InitializeResponse{}, err + return dbplugin.InitializeResponse{}, err } if i.ConnectTimeoutRaw == nil { @@ -62,16 +62,16 @@ func (i *influxdbConnectionProducer) Initialize(ctx context.Context, req newdbpl } i.connectTimeout, err = parseutil.ParseDurationSecond(i.ConnectTimeoutRaw) if err != nil { - return newdbplugin.InitializeResponse{}, errwrap.Wrapf("invalid connect_timeout: {{err}}", err) + return dbplugin.InitializeResponse{}, errwrap.Wrapf("invalid connect_timeout: {{err}}", err) } switch { 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: - return newdbplugin.InitializeResponse{}, fmt.Errorf("username cannot be empty") + return dbplugin.InitializeResponse{}, fmt.Errorf("username cannot be empty") 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 @@ -80,11 +80,11 @@ func (i *influxdbConnectionProducer) Initialize(ctx context.Context, req newdbpl case len(i.PemJSON) != 0: parsedCertBundle, err = certutil.ParsePKIJSON([]byte(i.PemJSON)) 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() 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.privateKey = certBundle.PrivateKey @@ -94,11 +94,11 @@ func (i *influxdbConnectionProducer) Initialize(ctx context.Context, req newdbpl case len(i.PemBundle) != 0: parsedCertBundle, err = certutil.ParsePEMBundle(i.PemBundle) 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() 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.privateKey = certBundle.PrivateKey @@ -112,11 +112,11 @@ func (i *influxdbConnectionProducer) Initialize(ctx context.Context, req newdbpl if req.VerifyConnection { 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, } diff --git a/plugins/database/influxdb/influxdb.go b/plugins/database/influxdb/influxdb.go index d6441fafb5a3..184e2b82244e 100644 --- a/plugins/database/influxdb/influxdb.go +++ b/plugins/database/influxdb/influxdb.go @@ -5,12 +5,11 @@ import ( "fmt" "strings" - "github.com/hashicorp/vault/sdk/database/helper/credsutil" - multierror "github.com/hashicorp/go-multierror" "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/newdbplugin" "github.com/hashicorp/vault/sdk/helper/strutil" influx "github.com/influxdata/influxdb/client/v2" ) @@ -22,7 +21,7 @@ const ( influxdbTypeName = "influxdb" ) -var _ newdbplugin.Database = &Influxdb{} +var _ dbplugin.Database = &Influxdb{} // Influxdb is an implementation of Database interface type Influxdb struct { @@ -32,7 +31,7 @@ type Influxdb struct { // New returns a new Cassandra instance func New() (interface{}, error) { db := new() - dbType := newdbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) + dbType := dbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) return dbType, nil } @@ -53,7 +52,7 @@ func Run(apiTLSConfig *api.TLSConfig) error { return err } - newdbplugin.Serve(dbType.(newdbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) + dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) 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 // 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() defer i.Unlock() cli, err := i.getConnection(ctx) 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 @@ -101,7 +100,7 @@ func (i *Influxdb) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) credsutil.ToLower(), ) 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) @@ -122,11 +121,11 @@ func (i *Influxdb) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) if response != nil && response.Error() != nil { 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, } return resp, nil @@ -157,13 +156,13 @@ func attemptRollback(cli influx.Client, username string, rollbackStatements []st 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() defer i.Unlock() cli, err := i.getConnection(ctx) 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 @@ -190,14 +189,14 @@ func (i *Influxdb) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserReq } } 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 { - return newdbplugin.UpdateUserResponse{}, fmt.Errorf("no changes requested") + return dbplugin.UpdateUserResponse{}, fmt.Errorf("no changes requested") } i.Lock() @@ -206,14 +205,14 @@ func (i *Influxdb) UpdateUser(ctx context.Context, req newdbplugin.UpdateUserReq if req.Password != nil { err := i.changeUserPassword(ctx, req.Username, req.Password) 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 - 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) if err != nil { return fmt.Errorf("unable to get connection: %w", err) diff --git a/plugins/database/influxdb/influxdb_test.go b/plugins/database/influxdb/influxdb_test.go index e3bf56948702..e3338da520a5 100644 --- a/plugins/database/influxdb/influxdb_test.go +++ b/plugins/database/influxdb/influxdb_test.go @@ -11,12 +11,10 @@ import ( "testing" "time" - "github.com/hashicorp/vault/sdk/database/newdbplugin" - - dbtesting "github.com/hashicorp/vault/sdk/database/newdbplugin/testing" - "github.com/hashicorp/errwrap" "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" ) @@ -101,78 +99,78 @@ func TestInfluxdb_Initialize(t *testing.T) { defer cleanup() type testCase struct { - req newdbplugin.InitializeRequest - expectedResponse newdbplugin.InitializeResponse + req dbplugin.InitializeRequest + expectedResponse dbplugin.InitializeResponse expectErr bool expectInitialized bool } tests := map[string]testCase{ "port is an int": { - req: newdbplugin.InitializeRequest{ + req: dbplugin.InitializeRequest{ Config: makeConfig(config.connectionParams()), VerifyConnection: true, }, - expectedResponse: newdbplugin.InitializeResponse{ + expectedResponse: dbplugin.InitializeResponse{ Config: config.connectionParams(), }, expectErr: false, expectInitialized: true, }, "port is a string": { - req: newdbplugin.InitializeRequest{ + req: dbplugin.InitializeRequest{ Config: makeConfig(config.connectionParams(), "port", strconv.Itoa(config.connectionParams()["port"].(int))), VerifyConnection: true, }, - expectedResponse: newdbplugin.InitializeResponse{ + expectedResponse: dbplugin.InitializeResponse{ Config: makeConfig(config.connectionParams(), "port", strconv.Itoa(config.connectionParams()["port"].(int))), }, expectErr: false, expectInitialized: true, }, "missing config": { - req: newdbplugin.InitializeRequest{ + req: dbplugin.InitializeRequest{ Config: nil, VerifyConnection: true, }, - expectedResponse: newdbplugin.InitializeResponse{}, + expectedResponse: dbplugin.InitializeResponse{}, expectErr: true, expectInitialized: false, }, "missing host": { - req: newdbplugin.InitializeRequest{ + req: dbplugin.InitializeRequest{ Config: makeConfig(config.connectionParams(), "host", ""), VerifyConnection: true, }, - expectedResponse: newdbplugin.InitializeResponse{}, + expectedResponse: dbplugin.InitializeResponse{}, expectErr: true, expectInitialized: false, }, "missing username": { - req: newdbplugin.InitializeRequest{ + req: dbplugin.InitializeRequest{ Config: makeConfig(config.connectionParams(), "username", ""), VerifyConnection: true, }, - expectedResponse: newdbplugin.InitializeResponse{}, + expectedResponse: dbplugin.InitializeResponse{}, expectErr: true, expectInitialized: false, }, "missing password": { - req: newdbplugin.InitializeRequest{ + req: dbplugin.InitializeRequest{ Config: makeConfig(config.connectionParams(), "password", ""), VerifyConnection: true, }, - expectedResponse: newdbplugin.InitializeResponse{}, + expectedResponse: dbplugin.InitializeResponse{}, expectErr: true, expectInitialized: false, }, "failed to validate connection": { - req: newdbplugin.InitializeRequest{ + req: dbplugin.InitializeRequest{ // Host exists, but isn't a running instance Config: makeConfig(config.connectionParams(), "host", "foobar://bad_connection"), VerifyConnection: true, }, - expectedResponse: newdbplugin.InitializeResponse{}, + expectedResponse: dbplugin.InitializeResponse{}, expectErr: true, expectInitialized: true, }, @@ -227,19 +225,19 @@ func TestInfluxdb_CreateUser(t *testing.T) { defer cleanup() db := new() - req := newdbplugin.InitializeRequest{ + req := dbplugin.InitializeRequest{ Config: config.connectionParams(), VerifyConnection: true, } dbtesting.AssertInitialize(t, db, req) password := "nuozxby98523u89bdfnkjl" - newUserReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + newUserReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{createUserStatements}, }, Password: password, @@ -261,19 +259,19 @@ func TestUpdateUser_expiration(t *testing.T) { defer cleanup() db := new() - req := newdbplugin.InitializeRequest{ + req := dbplugin.InitializeRequest{ Config: config.connectionParams(), VerifyConnection: true, } dbtesting.AssertInitialize(t, db, req) password := "nuozxby98523u89bdfnkjl" - newUserReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + newUserReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{createUserStatements}, }, Password: password, @@ -283,9 +281,9 @@ func TestUpdateUser_expiration(t *testing.T) { assertCredsExist(t, config.URL().String(), newUserResp.Username, password) - renewReq := newdbplugin.UpdateUserRequest{ + renewReq := dbplugin.UpdateUserRequest{ Username: newUserResp.Username, - Expiration: &newdbplugin.ChangeExpiration{ + Expiration: &dbplugin.ChangeExpiration{ NewExpiration: time.Now().Add(5 * time.Minute), }, } @@ -300,19 +298,19 @@ func TestUpdateUser_password(t *testing.T) { defer cleanup() db := new() - req := newdbplugin.InitializeRequest{ + req := dbplugin.InitializeRequest{ Config: config.connectionParams(), VerifyConnection: true, } dbtesting.AssertInitialize(t, db, req) initialPassword := "nuozxby98523u89bdfnkjl" - newUserReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + newUserReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{createUserStatements}, }, Password: initialPassword, @@ -323,9 +321,9 @@ func TestUpdateUser_password(t *testing.T) { assertCredsExist(t, config.URL().String(), newUserResp.Username, initialPassword) newPassword := "y89qgmbzadiygry8uazodijnb" - newPasswordReq := newdbplugin.UpdateUserRequest{ + newPasswordReq := dbplugin.UpdateUserRequest{ Username: newUserResp.Username, - Password: &newdbplugin.ChangePassword{ + Password: &dbplugin.ChangePassword{ NewPassword: newPassword, }, } @@ -346,14 +344,14 @@ func TestInfluxdb_RevokeDeletedUser(t *testing.T) { defer cleanup() db := new() - req := newdbplugin.InitializeRequest{ + req := dbplugin.InitializeRequest{ Config: config.connectionParams(), VerifyConnection: true, } dbtesting.AssertInitialize(t, db, req) // attempt to revoke a user that does not exist - delReq := newdbplugin.DeleteUserRequest{ + delReq := dbplugin.DeleteUserRequest{ Username: "someuser", } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) @@ -369,19 +367,19 @@ func TestInfluxdb_RevokeUser(t *testing.T) { defer cleanup() db := new() - req := newdbplugin.InitializeRequest{ + req := dbplugin.InitializeRequest{ Config: config.connectionParams(), VerifyConnection: true, } dbtesting.AssertInitialize(t, db, req) initialPassword := "nuozxby98523u89bdfnkjl" - newUserReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + newUserReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{createUserStatements}, }, Password: initialPassword, @@ -391,7 +389,7 @@ func TestInfluxdb_RevokeUser(t *testing.T) { assertCredsExist(t, config.URL().String(), newUserResp.Username, initialPassword) - delReq := newdbplugin.DeleteUserRequest{ + delReq := dbplugin.DeleteUserRequest{ Username: newUserResp.Username, } dbtesting.AssertDeleteUser(t, db, delReq) diff --git a/plugins/database/mongodb/connection_producer.go b/plugins/database/mongodb/connection_producer.go index 59047e0042ff..f160c0a043dd 100644 --- a/plugins/database/mongodb/connection_producer.go +++ b/plugins/database/mongodb/connection_producer.go @@ -10,10 +10,9 @@ import ( "sync" "time" + "github.com/hashicorp/errwrap" "github.com/hashicorp/vault/sdk/database/helper/connutil" "github.com/hashicorp/vault/sdk/database/helper/dbutil" - - "github.com/hashicorp/errwrap" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/readpref" diff --git a/plugins/database/mongodb/connection_producer_test.go b/plugins/database/mongodb/connection_producer_test.go index 19b6e94ebf31..89880a6d1d8b 100644 --- a/plugins/database/mongodb/connection_producer_test.go +++ b/plugins/database/mongodb/connection_producer_test.go @@ -15,7 +15,7 @@ import ( "github.com/hashicorp/vault/helper/testhelpers/certhelpers" "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" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -79,7 +79,7 @@ net: // Test mongo := new() - initReq := newdbplugin.InitializeRequest{ + initReq := dbplugin.InitializeRequest{ Config: map[string]interface{}{ "connection_url": retURL, "allowed_roles": "*", diff --git a/plugins/database/mongodb/mongodb.go b/plugins/database/mongodb/mongodb.go index a3029292a416..8d78c92f87e8 100644 --- a/plugins/database/mongodb/mongodb.go +++ b/plugins/database/mongodb/mongodb.go @@ -8,9 +8,9 @@ import ( "strings" "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/newdbplugin" "github.com/mitchellh/mapstructure" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" @@ -26,12 +26,12 @@ type MongoDB struct { *mongoDBConnectionProducer } -var _ newdbplugin.Database = &MongoDB{} +var _ dbplugin.Database = &MongoDB{} // New returns a new MongoDB instance func New() (interface{}, error) { db := new() - dbType := newdbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) + dbType := dbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) return dbType, nil } @@ -52,7 +52,7 @@ func Run(apiTLSConfig *api.TLSConfig) error { return err } - newdbplugin.Serve(dbType.(newdbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) + dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) return nil } @@ -71,7 +71,7 @@ func (m *MongoDB) getConnection(ctx context.Context) (*mongo.Client, error) { 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() defer m.Unlock() @@ -79,21 +79,21 @@ func (m *MongoDB) Initialize(ctx context.Context, req newdbplugin.InitializeRequ err := mapstructure.WeakDecode(req.Config, m.mongoDBConnectionProducer) if err != nil { - return newdbplugin.InitializeResponse{}, err + return dbplugin.InitializeResponse{}, err } 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() if err != nil { - return newdbplugin.InitializeResponse{}, err + return dbplugin.InitializeResponse{}, err } authOpts, err := m.getTLSAuth() if err != nil { - return newdbplugin.InitializeResponse{}, err + return dbplugin.InitializeResponse{}, err } m.clientOptions = options.MergeClientOptions(writeOpts, authOpts) @@ -105,28 +105,28 @@ func (m *MongoDB) Initialize(ctx context.Context, req newdbplugin.InitializeRequ if req.VerifyConnection { _, err := m.Connection(ctx) 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()) 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, } 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 m.Lock() defer m.Unlock() if len(req.Statements.Commands) == 0 { - return newdbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement + return dbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement } username, err := credsutil.GenerateUsername( @@ -136,14 +136,14 @@ func (m *MongoDB) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) ( credsutil.Separator("-"), ) if err != nil { - return newdbplugin.NewUserResponse{}, err + return dbplugin.NewUserResponse{}, err } // Unmarshal statements.CreationStatements into mongodbRoles var mongoCS mongoDBStatement err = json.Unmarshal([]byte(req.Statements.Commands[0]), &mongoCS) if err != nil { - return newdbplugin.NewUserResponse{}, err + return dbplugin.NewUserResponse{}, err } // 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 { - 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{ @@ -162,21 +162,21 @@ func (m *MongoDB) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) ( } 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, } 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 { 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 { @@ -208,7 +208,7 @@ func (m *MongoDB) changeUserPassword(ctx context.Context, username, password str 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() defer m.Unlock() @@ -220,14 +220,14 @@ func (m *MongoDB) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserRequ case 1: revocationStatement = req.Statements.Commands[0] 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 var mongoCS mongoDBStatement err := json.Unmarshal([]byte(revocationStatement), &mongoCS) if err != nil { - return newdbplugin.DeleteUserResponse{}, err + return dbplugin.DeleteUserResponse{}, err } db := mongoCS.DB @@ -242,7 +242,7 @@ func (m *MongoDB) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserRequ } 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 diff --git a/plugins/database/mongodb/mongodb_test.go b/plugins/database/mongodb/mongodb_test.go index 9bc9f8eca41a..b07cc75f0880 100644 --- a/plugins/database/mongodb/mongodb_test.go +++ b/plugins/database/mongodb/mongodb_test.go @@ -12,8 +12,8 @@ import ( "github.com/hashicorp/vault/helper/testhelpers/certhelpers" "github.com/hashicorp/vault/helper/testhelpers/mongodb" - "github.com/hashicorp/vault/sdk/database/newdbplugin" - dbtesting "github.com/hashicorp/vault/sdk/database/newdbplugin/testing" + dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" + dbtesting "github.com/hashicorp/vault/sdk/database/dbplugin/v5/testing" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "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 expectedConfig := copyConfig(config) - req := newdbplugin.InitializeRequest{ + req := dbplugin.InitializeRequest{ Config: config, VerifyConnection: true, } @@ -58,7 +58,7 @@ func TestMongoDB_CreateUser(t *testing.T) { db := new() defer dbtesting.AssertClose(t, db) - initReq := newdbplugin.InitializeRequest{ + initReq := dbplugin.InitializeRequest{ Config: map[string]interface{}{ "connection_url": connURL, }, @@ -67,12 +67,12 @@ func TestMongoDB_CreateUser(t *testing.T) { dbtesting.AssertInitialize(t, db, initReq) password := "myreallysecurepassword" - createReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + createReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{mongoAdminRole}, }, Password: password, @@ -87,7 +87,7 @@ func TestMongoDB_CreateUser_writeConcern(t *testing.T) { cleanup, connURL := mongodb.PrepareTestContainer(t, "latest") defer cleanup() - initReq := newdbplugin.InitializeRequest{ + initReq := dbplugin.InitializeRequest{ Config: map[string]interface{}{ "connection_url": connURL, "write_concern": `{ "wmode": "majority", "wtimeout": 5000 }`, @@ -101,12 +101,12 @@ func TestMongoDB_CreateUser_writeConcern(t *testing.T) { dbtesting.AssertInitialize(t, db, initReq) password := "myreallysecurepassword" - createReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + createReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{mongoAdminRole}, }, Password: password, @@ -124,7 +124,7 @@ func TestMongoDB_DeleteUser(t *testing.T) { db := new() defer dbtesting.AssertClose(t, db) - initReq := newdbplugin.InitializeRequest{ + initReq := dbplugin.InitializeRequest{ Config: map[string]interface{}{ "connection_url": connURL, }, @@ -133,12 +133,12 @@ func TestMongoDB_DeleteUser(t *testing.T) { dbtesting.AssertInitialize(t, db, initReq) password := "myreallysecurepassword" - createReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + createReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{mongoAdminRole}, }, Password: password, @@ -148,7 +148,7 @@ func TestMongoDB_DeleteUser(t *testing.T) { assertCredsExist(t, createResp.Username, password, connURL) // Test default revocation statement - delReq := newdbplugin.DeleteUserRequest{ + delReq := dbplugin.DeleteUserRequest{ Username: createResp.Username, } @@ -167,7 +167,7 @@ func TestMongoDB_UpdateUser_Password(t *testing.T) { db := new() defer dbtesting.AssertClose(t, db) - initReq := newdbplugin.InitializeRequest{ + initReq := dbplugin.InitializeRequest{ Config: map[string]interface{}{ "connection_url": connURL, }, @@ -182,9 +182,9 @@ func TestMongoDB_UpdateUser_Password(t *testing.T) { newPassword := "myreallysecurecredentials" - updateReq := newdbplugin.UpdateUserRequest{ + updateReq := dbplugin.UpdateUserRequest{ Username: dbUser, - Password: &newdbplugin.ChangePassword{ + Password: &dbplugin.ChangePassword{ NewPassword: newPassword, }, } diff --git a/plugins/database/mssql/mssql.go b/plugins/database/mssql/mssql.go index 4d0e466071d8..adcc00b7259b 100644 --- a/plugins/database/mssql/mssql.go +++ b/plugins/database/mssql/mssql.go @@ -11,17 +11,17 @@ import ( "github.com/hashicorp/errwrap" multierror "github.com/hashicorp/go-multierror" "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/credsutil" "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/strutil" ) const msSQLTypeName = "mssql" -var _ newdbplugin.Database = &MSSQL{} +var _ dbplugin.Database = &MSSQL{} // MSSQL is an implementation of Database interface type MSSQL struct { @@ -31,7 +31,7 @@ type MSSQL struct { func New() (interface{}, error) { db := new() // Wrap the plugin with middleware to sanitize errors - dbType := newdbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) + dbType := dbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) return dbType, nil } @@ -52,7 +52,7 @@ func Run(apiTLSConfig *api.TLSConfig) error { return err } - newdbplugin.Serve(dbType.(newdbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) + dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) return nil } @@ -77,12 +77,12 @@ func (m *MSSQL) getConnection(ctx context.Context) (*sql.DB, error) { 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) if err != nil { - return newdbplugin.InitializeResponse{}, err + return dbplugin.InitializeResponse{}, err } - resp := newdbplugin.InitializeResponse{ + resp := dbplugin.InitializeResponse{ Config: newConf, } 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 // 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() defer m.Unlock() db, err := m.getConnection(ctx) 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 { - return newdbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement + return dbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement } username, err := credsutil.GenerateUsername( @@ -110,14 +110,14 @@ func (m *MSSQL) NewUser(ctx context.Context, req newdbplugin.NewUserRequest) (ne credsutil.Separator("-"), ) if err != nil { - return newdbplugin.NewUserResponse{}, err + return dbplugin.NewUserResponse{}, err } expirationStr := req.Expiration.Format("2006-01-02 15:04:05-0700") tx, err := db.BeginTx(ctx, nil) if err != nil { - return newdbplugin.NewUserResponse{}, err + return dbplugin.NewUserResponse{}, err } 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 { - return newdbplugin.NewUserResponse{}, err + return dbplugin.NewUserResponse{}, err } } } if err := tx.Commit(); err != nil { - return newdbplugin.NewUserResponse{}, err + return dbplugin.NewUserResponse{}, err } - resp := newdbplugin.NewUserResponse{ + resp := dbplugin.NewUserResponse{ 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, // then kill pending connections from that user, and finally drop the user and login from the // 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 { err := m.revokeUserDefault(ctx, req.Username) - return newdbplugin.DeleteUserResponse{}, err + return dbplugin.DeleteUserResponse{}, err } db, err := m.getConnection(ctx) 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{} @@ -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 { @@ -290,19 +290,19 @@ func (m *MSSQL) revokeUserDefault(ctx context.Context, username string) error { 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 { - return newdbplugin.UpdateUserResponse{}, fmt.Errorf("no changes requested") + return dbplugin.UpdateUserResponse{}, fmt.Errorf("no changes requested") } if req.Password != nil { err := m.updateUserPass(ctx, req.Username, req.Password) - return newdbplugin.UpdateUserResponse{}, err + return dbplugin.UpdateUserResponse{}, err } // 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 if len(stmts) == 0 { stmts = []string{alterLoginSQL} diff --git a/plugins/database/mssql/mssql_test.go b/plugins/database/mssql/mssql_test.go index 1bf108dc0f1b..a14d6016177b 100644 --- a/plugins/database/mssql/mssql_test.go +++ b/plugins/database/mssql/mssql_test.go @@ -10,11 +10,10 @@ import ( "testing" "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" + 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) { @@ -22,12 +21,12 @@ func TestInitialize(t *testing.T) { defer cleanup() type testCase struct { - req newdbplugin.InitializeRequest + req dbplugin.InitializeRequest } tests := map[string]testCase{ "happy path": { - req: newdbplugin.InitializeRequest{ + req: dbplugin.InitializeRequest{ Config: map[string]interface{}{ "connection_url": connURL, }, @@ -35,7 +34,7 @@ func TestInitialize(t *testing.T) { }, }, "max_open_connections set": { - newdbplugin.InitializeRequest{ + dbplugin.InitializeRequest{ Config: map[string]interface{}{ "connection_url": connURL, "max_open_connections": "5", @@ -63,7 +62,7 @@ func TestNewUser(t *testing.T) { defer cleanup() type testCase struct { - req newdbplugin.NewUserRequest + req dbplugin.NewUserRequest usernameRegex string expectErr bool assertUser func(t testing.TB, connURL, username, password string) @@ -71,12 +70,12 @@ func TestNewUser(t *testing.T) { tests := map[string]testCase{ "no creation statements": { - req: newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + req: dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{}, + Statements: dbplugin.Statements{}, Password: "AG4qagho-dsvZ", Expiration: time.Now().Add(1 * time.Second), }, @@ -85,12 +84,12 @@ func TestNewUser(t *testing.T) { assertUser: assertCredsDoNotExist, }, "with creation statements": { - req: newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + req: dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{testMSSQLRole}, }, Password: "AG4qagho-dsvZ", @@ -109,7 +108,7 @@ func TestNewUser(t *testing.T) { t.Fatalf("failed to compile username regex %q: %s", test.usernameRegex, err) } - initReq := newdbplugin.InitializeRequest{ + initReq := dbplugin.InitializeRequest{ Config: map[string]interface{}{ "connection_url": connURL, }, @@ -133,7 +132,7 @@ func TestNewUser(t *testing.T) { } // Protect against future fields that aren't specified - expectedResp := newdbplugin.NewUserResponse{ + expectedResp := dbplugin.NewUserResponse{ Username: createResp.Username, } if !reflect.DeepEqual(createResp, expectedResp) { @@ -147,7 +146,7 @@ func TestNewUser(t *testing.T) { func TestUpdateUser_password(t *testing.T) { type testCase struct { - req newdbplugin.UpdateUserRequest + req dbplugin.UpdateUserRequest expectErr bool expectedPassword string } @@ -157,33 +156,33 @@ func TestUpdateUser_password(t *testing.T) { tests := map[string]testCase{ "missing password": { - req: newdbplugin.UpdateUserRequest{ + req: dbplugin.UpdateUserRequest{ Username: dbUser, - Password: &newdbplugin.ChangePassword{ + Password: &dbplugin.ChangePassword{ NewPassword: "", - Statements: newdbplugin.Statements{}, + Statements: dbplugin.Statements{}, }, }, expectErr: true, expectedPassword: initPassword, }, "empty rotation statements": { - req: newdbplugin.UpdateUserRequest{ + req: dbplugin.UpdateUserRequest{ Username: dbUser, - Password: &newdbplugin.ChangePassword{ + Password: &dbplugin.ChangePassword{ NewPassword: "N90gkKLy8$angf", - Statements: newdbplugin.Statements{}, + Statements: dbplugin.Statements{}, }, }, expectErr: false, expectedPassword: "N90gkKLy8$angf", }, "username rotation": { - req: newdbplugin.UpdateUserRequest{ + req: dbplugin.UpdateUserRequest{ Username: dbUser, - Password: &newdbplugin.ChangePassword{ + Password: &dbplugin.ChangePassword{ NewPassword: "N90gkKLy8$angf", - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{ "ALTER LOGIN [{{username}}] WITH PASSWORD = '{{password}}'", }, @@ -194,11 +193,11 @@ func TestUpdateUser_password(t *testing.T) { expectedPassword: "N90gkKLy8$angf", }, "bad statements": { - req: newdbplugin.UpdateUserRequest{ + req: dbplugin.UpdateUserRequest{ Username: dbUser, - Password: &newdbplugin.ChangePassword{ + Password: &dbplugin.ChangePassword{ NewPassword: "N90gkKLy8$angf", - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{ "ahosh98asjdffs", }, @@ -215,7 +214,7 @@ func TestUpdateUser_password(t *testing.T) { cleanup, connURL := mssqlhelper.PrepareMSSQLTestContainer(t) defer cleanup() - initReq := newdbplugin.InitializeRequest{ + initReq := dbplugin.InitializeRequest{ Config: map[string]interface{}{ "connection_url": connURL, }, @@ -241,7 +240,7 @@ func TestUpdateUser_password(t *testing.T) { } // Protect against future fields that aren't specified - expectedResp := newdbplugin.UpdateUserResponse{} + expectedResp := dbplugin.UpdateUserResponse{} if !reflect.DeepEqual(updateResp, expectedResp) { t.Fatalf("Fields missing from expected response: Actual: %#v", updateResp) } @@ -258,7 +257,7 @@ func TestDeleteUser(t *testing.T) { dbUser := "vaultuser" initPassword := "p4$sw0rd" - initReq := newdbplugin.InitializeRequest{ + initReq := dbplugin.InitializeRequest{ Config: map[string]interface{}{ "connection_url": connURL, }, @@ -273,7 +272,7 @@ func TestDeleteUser(t *testing.T) { assertCredsExist(t, connURL, dbUser, initPassword) - deleteReq := newdbplugin.DeleteUserRequest{ + deleteReq := dbplugin.DeleteUserRequest{ Username: dbUser, } @@ -285,7 +284,7 @@ func TestDeleteUser(t *testing.T) { } // Protect against future fields that aren't specified - expectedResp := newdbplugin.DeleteUserResponse{} + expectedResp := dbplugin.DeleteUserResponse{} if !reflect.DeepEqual(deleteResp, expectedResp) { t.Fatalf("Fields missing from expected response: Actual: %#v", deleteResp) } diff --git a/plugins/database/mysql/mysql.go b/plugins/database/mysql/mysql.go index 1319854099dc..6f28683e617a 100644 --- a/plugins/database/mysql/mysql.go +++ b/plugins/database/mysql/mysql.go @@ -7,14 +7,13 @@ import ( "fmt" "strings" + stdmysql "github.com/go-sql-driver/mysql" "github.com/hashicorp/errwrap" "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/newdbplugin" "github.com/hashicorp/vault/sdk/helper/strutil" - - stdmysql "github.com/go-sql-driver/mysql" ) const ( @@ -37,7 +36,7 @@ var ( LegacyUsernameLen int = 16 ) -var _ newdbplugin.Database = (*MySQL)(nil) +var _ dbplugin.Database = (*MySQL)(nil) type MySQL struct { *mySQLConnectionProducer @@ -49,7 +48,7 @@ func New(legacy bool) func() (interface{}, error) { return func() (interface{}, error) { db := new(legacy) // Wrap the plugin with middleware to sanitize errors - dbType := newdbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.SecretValues) + dbType := dbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.SecretValues) return dbType, nil } @@ -82,7 +81,7 @@ func runCommon(legacy bool, apiTLSConfig *api.TLSConfig) error { return err } - newdbplugin.Serve(dbType.(newdbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) + dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) return nil } @@ -100,25 +99,25 @@ func (m *MySQL) getConnection(ctx context.Context) (*sql.DB, error) { 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) if err != nil { - return newdbplugin.InitializeResponse{}, err + return dbplugin.InitializeResponse{}, err } - resp := newdbplugin.InitializeResponse{ + resp := dbplugin.InitializeResponse{ Config: req.Config, } 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 { - return newdbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement + return dbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement } username, err := m.generateUsername(req) if err != nil { - return newdbplugin.NewUserResponse{}, err + return dbplugin.NewUserResponse{}, err } 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 { - return newdbplugin.NewUserResponse{}, err + return dbplugin.NewUserResponse{}, err } - resp := newdbplugin.NewUserResponse{ + resp := dbplugin.NewUserResponse{ Username: username, } 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 if m.legacy { @@ -167,7 +166,7 @@ func (m *MySQL) generateUsername(req newdbplugin.NewUserRequest) (string, error) 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 m.Lock() defer m.Unlock() @@ -175,7 +174,7 @@ func (m *MySQL) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserReques // Get the connection db, err := m.getConnection(ctx) if err != nil { - return newdbplugin.DeleteUserResponse{}, err + return dbplugin.DeleteUserResponse{}, err } revocationStmts := req.Statements.Commands @@ -187,7 +186,7 @@ func (m *MySQL) DeleteUser(ctx context.Context, req newdbplugin.DeleteUserReques // Start a transaction tx, err := db.BeginTx(ctx, nil) if err != nil { - return newdbplugin.DeleteUserResponse{}, err + return dbplugin.DeleteUserResponse{}, err } 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) _, err = tx.ExecContext(ctx, query) if err != nil { - return newdbplugin.DeleteUserResponse{}, err + return dbplugin.DeleteUserResponse{}, err } } } // Commit the transaction 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 { - return newdbplugin.UpdateUserResponse{}, fmt.Errorf("no change requested") + return dbplugin.UpdateUserResponse{}, fmt.Errorf("no change requested") } if req.Password != nil { err := m.changeUserPassword(ctx, req.Username, req.Password.NewPassword, req.Password.Statements.Commands) 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 - return newdbplugin.UpdateUserResponse{}, nil + return dbplugin.UpdateUserResponse{}, nil } func (m *MySQL) changeUserPassword(ctx context.Context, username, password string, rotateStatements []string) error { diff --git a/plugins/database/mysql/mysql_test.go b/plugins/database/mysql/mysql_test.go index ac9ff622137c..5d6eda2f0f5a 100644 --- a/plugins/database/mysql/mysql_test.go +++ b/plugins/database/mysql/mysql_test.go @@ -9,14 +9,13 @@ import ( stdmysql "github.com/go-sql-driver/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/dbutil" - "github.com/hashicorp/vault/sdk/database/newdbplugin" "github.com/hashicorp/vault/sdk/helper/strutil" ) -var _ newdbplugin.Database = (*MySQL)(nil) +var _ dbplugin.Database = (*MySQL)(nil) func TestMySQL_Initialize(t *testing.T) { cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret") @@ -26,7 +25,7 @@ func TestMySQL_Initialize(t *testing.T) { "connection_url": connURL, } - initReq := newdbplugin.InitializeRequest{ + initReq := dbplugin.InitializeRequest{ Config: connectionDetails, VerifyConnection: true, } @@ -52,7 +51,7 @@ func TestMySQL_Initialize(t *testing.T) { "max_open_connections": "5", } - initReq = newdbplugin.InitializeRequest{ + initReq = dbplugin.InitializeRequest{ Config: connectionDetails, VerifyConnection: true, } @@ -73,12 +72,12 @@ func TestMySQL_CreateUser(t *testing.T) { t.Fatalf("unable to generate password: %s", err) } - createReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + createReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{}, }, Password: password, @@ -103,7 +102,7 @@ func TestMySQL_CreateUser(t *testing.T) { "connection_url": connURL, } - initReq := newdbplugin.InitializeRequest{ + initReq := dbplugin.InitializeRequest{ Config: connectionDetails, VerifyConnection: true, } @@ -126,7 +125,7 @@ func TestMySQL_CreateUser(t *testing.T) { "connection_url": connURL, } - initReq := newdbplugin.InitializeRequest{ + initReq := dbplugin.InitializeRequest{ Config: connectionDetails, VerifyConnection: true, } @@ -188,12 +187,12 @@ func testCreateUser(t *testing.T, db *MySQL, connURL string) { t.Fatalf("unable to generate password: %s", err) } - createReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + createReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: test.createStmts, }, Password: password, @@ -256,7 +255,7 @@ func TestMySQL_RotateRootCredentials(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - initReq := newdbplugin.InitializeRequest{ + initReq := dbplugin.InitializeRequest{ Config: connectionDetails, VerifyConnection: true, } @@ -271,11 +270,11 @@ func TestMySQL_RotateRootCredentials(t *testing.T) { t.Fatal("Database should be initialized") } - updateReq := newdbplugin.UpdateUserRequest{ + updateReq := dbplugin.UpdateUserRequest{ Username: "root", - Password: &newdbplugin.ChangePassword{ + Password: &dbplugin.ChangePassword{ NewPassword: "different_sercret", - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: test.statements, }, }, @@ -331,7 +330,7 @@ func TestMySQL_DeleteUser(t *testing.T) { "connection_url": connURL, } - initReq := newdbplugin.InitializeRequest{ + initReq := dbplugin.InitializeRequest{ Config: connectionDetails, VerifyConnection: true, } @@ -349,12 +348,12 @@ func TestMySQL_DeleteUser(t *testing.T) { t.Fatalf("unable to generate password: %s", err) } - createReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + createReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{` CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; 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) } - deleteReq := newdbplugin.DeleteUserRequest{ + deleteReq := dbplugin.DeleteUserRequest{ Username: userResp.Username, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: test.revokeStmts, }, } @@ -436,7 +435,7 @@ func TestMySQL_UpdateUser(t *testing.T) { "connection_url": connURL, } - initReq := newdbplugin.InitializeRequest{ + initReq := dbplugin.InitializeRequest{ Config: connectionDetails, VerifyConnection: true, } @@ -456,11 +455,11 @@ func TestMySQL_UpdateUser(t *testing.T) { t.Fatalf("unable to generate password: %s", err) } - updateReq := newdbplugin.UpdateUserRequest{ + updateReq := dbplugin.UpdateUserRequest{ Username: dbUser, - Password: &newdbplugin.ChangePassword{ + Password: &dbplugin.ChangePassword{ NewPassword: newPassword, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: test.rotateStmts, }, }, diff --git a/plugins/database/postgresql/postgresql.go b/plugins/database/postgresql/postgresql.go index d8aa0a094d22..5df9d6ef8f7c 100644 --- a/plugins/database/postgresql/postgresql.go +++ b/plugins/database/postgresql/postgresql.go @@ -10,10 +10,10 @@ import ( "github.com/hashicorp/errwrap" "github.com/hashicorp/go-multierror" "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/credsutil" "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/strutil" "github.com/lib/pq" @@ -32,7 +32,7 @@ ALTER ROLE "{{username}}" WITH PASSWORD '{{password}}'; ) var ( - _ newdbplugin.Database = &PostgreSQL{} + _ dbplugin.Database = &PostgreSQL{} // postgresEndStatement is basically the word "END" but // surrounded by a word boundary to differentiate it from @@ -52,7 +52,7 @@ var ( func New() (interface{}, error) { db := new() // Wrap the plugin with middleware to sanitize errors - dbType := newdbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) + dbType := dbplugin.NewDatabaseErrorSanitizerMiddleware(db, db.secretValues) return dbType, nil } @@ -74,7 +74,7 @@ func Run(apiTLSConfig *api.TLSConfig) error { return err } - newdbplugin.Serve(dbType.(newdbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) + dbplugin.Serve(dbType.(dbplugin.Database), api.VaultPluginTLSProvider(apiTLSConfig)) return nil } @@ -83,12 +83,12 @@ type PostgreSQL struct { *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) if err != nil { - return newdbplugin.InitializeResponse{}, err + return dbplugin.InitializeResponse{}, err } - resp := newdbplugin.InitializeResponse{ + resp := dbplugin.InitializeResponse{ Config: newConf, } return resp, nil @@ -107,12 +107,12 @@ func (p *PostgreSQL) getConnection(ctx context.Context) (*sql.DB, error) { 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 == "" { - return newdbplugin.UpdateUserResponse{}, fmt.Errorf("missing username") + return dbplugin.UpdateUserResponse{}, fmt.Errorf("missing username") } 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{} @@ -124,10 +124,10 @@ func (p *PostgreSQL) UpdateUser(ctx context.Context, req newdbplugin.UpdateUserR err := p.changeUserExpiration(ctx, req.Username, req.Expiration) 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 if len(stmts) == 0 { stmts = []string{defaultChangePasswordStatement} @@ -184,7 +184,7 @@ func (p *PostgreSQL) changeUserPassword(ctx context.Context, username string, ch 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() defer p.Unlock() @@ -229,9 +229,9 @@ func (p *PostgreSQL) changeUserExpiration(ctx context.Context, username string, 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 { - return newdbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement + return dbplugin.NewUserResponse{}, dbutil.ErrEmptyCreationStatement } p.Lock() @@ -244,19 +244,19 @@ func (p *PostgreSQL) NewUser(ctx context.Context, req newdbplugin.NewUserRequest credsutil.MaxLength(63), ) if err != nil { - return newdbplugin.NewUserResponse{}, err + return dbplugin.NewUserResponse{}, err } expirationStr := req.Expiration.Format(expirationFormat) db, err := p.getConnection(ctx) 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) 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() @@ -271,7 +271,7 @@ func (p *PostgreSQL) NewUser(ctx context.Context, req newdbplugin.NewUserRequest "expiration": expirationStr, } 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 } @@ -289,30 +289,30 @@ func (p *PostgreSQL) NewUser(ctx context.Context, req newdbplugin.NewUserRequest "expiration": expirationStr, } 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 { - return newdbplugin.NewUserResponse{}, err + return dbplugin.NewUserResponse{}, err } - resp := newdbplugin.NewUserResponse{ + resp := dbplugin.NewUserResponse{ Username: username, } 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() defer p.Unlock() 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 { diff --git a/plugins/database/postgresql/postgresql_test.go b/plugins/database/postgresql/postgresql_test.go index fa86af3f3caf..1cb6bf2d9134 100644 --- a/plugins/database/postgresql/postgresql_test.go +++ b/plugins/database/postgresql/postgresql_test.go @@ -9,8 +9,8 @@ import ( "time" "github.com/hashicorp/vault/helper/testhelpers/postgresql" - "github.com/hashicorp/vault/sdk/database/newdbplugin" - dbtesting "github.com/hashicorp/vault/sdk/database/newdbplugin/testing" + dbplugin "github.com/hashicorp/vault/sdk/database/dbplugin/v5" + dbtesting "github.com/hashicorp/vault/sdk/database/dbplugin/v5/testing" ) 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 } - req := newdbplugin.InitializeRequest{ + req := dbplugin.InitializeRequest{ Config: connectionDetails, VerifyConnection: true, } @@ -61,15 +61,15 @@ func TestPostgreSQL_InitializeWithStringVals(t *testing.T) { func TestPostgreSQL_NewUser(t *testing.T) { type testCase struct { - req newdbplugin.NewUserRequest + req dbplugin.NewUserRequest expectErr bool credsAssertion credsAssertion } tests := map[string]testCase{ "no creation statements": { - req: newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + req: dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, @@ -81,12 +81,12 @@ func TestPostgreSQL_NewUser(t *testing.T) { credsAssertion: assertCredsDoNotExist, }, "admin name": { - req: newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + req: dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{` CREATE ROLE "{{name}}" WITH LOGIN @@ -102,12 +102,12 @@ func TestPostgreSQL_NewUser(t *testing.T) { credsAssertion: assertCredsExist, }, "admin username": { - req: newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + req: dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{` CREATE ROLE "{{username}}" WITH LOGIN @@ -123,12 +123,12 @@ func TestPostgreSQL_NewUser(t *testing.T) { credsAssertion: assertCredsExist, }, "read only name": { - req: newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + req: dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{` CREATE ROLE "{{name}}" WITH LOGIN @@ -145,12 +145,12 @@ func TestPostgreSQL_NewUser(t *testing.T) { credsAssertion: assertCredsExist, }, "read only username": { - req: newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + req: dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{` CREATE ROLE "{{username}}" WITH LOGIN @@ -168,12 +168,12 @@ func TestPostgreSQL_NewUser(t *testing.T) { }, // https://github.com/hashicorp/vault/issues/6098 "reproduce GH-6098": { - req: newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + req: dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{ // 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 $$", @@ -186,12 +186,12 @@ func TestPostgreSQL_NewUser(t *testing.T) { credsAssertion: assertCredsDoNotExist, }, "reproduce issue with template": { - req: newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + req: dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{ `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, }, "large block statements": { - req: newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + req: dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: newUserLargeBlockStatements, }, Password: "somesecurepassword", @@ -284,12 +284,12 @@ func TestUpdateUser_Password(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { initialPass := "myreallysecurepassword" - createReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + createReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{createAdminUser}, }, Password: initialPass, @@ -300,11 +300,11 @@ func TestUpdateUser_Password(t *testing.T) { assertCredsExist(t, db.ConnectionURL, createResp.Username, initialPass) newPass := "somenewpassword" - updateReq := newdbplugin.UpdateUserRequest{ + updateReq := dbplugin.UpdateUserRequest{ Username: createResp.Username, - Password: &newdbplugin.ChangePassword{ + Password: &dbplugin.ChangePassword{ NewPassword: newPass, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: test.statements, }, }, @@ -326,11 +326,11 @@ func TestUpdateUser_Password(t *testing.T) { t.Run("user does not exist", func(t *testing.T) { newPass := "somenewpassword" - updateReq := newdbplugin.UpdateUserRequest{ + updateReq := dbplugin.UpdateUserRequest{ Username: "missing-user", - Password: &newdbplugin.ChangePassword{ + Password: &dbplugin.ChangePassword{ 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) { password := "myreallysecurepassword" initialExpiration := test.initialExpiration.Truncate(time.Second) - createReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + createReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{createAdminUser}, }, Password: password, @@ -418,11 +418,11 @@ func TestUpdateUser_Expiration(t *testing.T) { } newExpiration := test.newExpiration.Truncate(time.Second) - updateReq := newdbplugin.UpdateUserRequest{ + updateReq := dbplugin.UpdateUserRequest{ Username: createResp.Username, - Expiration: &newdbplugin.ChangeExpiration{ + Expiration: &dbplugin.ChangeExpiration{ NewExpiration: newExpiration, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: test.statements, }, }, @@ -538,12 +538,12 @@ func TestDeleteUser(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { password := "myreallysecurepassword" - createReq := newdbplugin.NewUserRequest{ - UsernameConfig: newdbplugin.UsernameMetadata{ + createReq := dbplugin.NewUserRequest{ + UsernameConfig: dbplugin.UsernameMetadata{ DisplayName: "test", RoleName: "test", }, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: []string{createAdminUser}, }, Password: password, @@ -553,9 +553,9 @@ func TestDeleteUser(t *testing.T) { assertCredsExist(t, db.ConnectionURL, createResp.Username, password) - deleteReq := newdbplugin.DeleteUserRequest{ + deleteReq := dbplugin.DeleteUserRequest{ Username: createResp.Username, - Statements: newdbplugin.Statements{ + Statements: dbplugin.Statements{ Commands: test.revokeStmts, }, } diff --git a/sdk/database/dbplugin/v5/conversions_test.go b/sdk/database/dbplugin/v5/conversions_test.go new file mode 100644 index 000000000000..ca98d4f3dd51 --- /dev/null +++ b/sdk/database/dbplugin/v5/conversions_test.go @@ -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 +} diff --git a/sdk/database/dbplugin/v5/database.go b/sdk/database/dbplugin/v5/database.go new file mode 100644 index 000000000000..225e94280a36 --- /dev/null +++ b/sdk/database/dbplugin/v5/database.go @@ -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 +} diff --git a/sdk/database/dbplugin/v5/grpc_client.go b/sdk/database/dbplugin/v5/grpc_client.go new file mode 100644 index 000000000000..47bb1d0a3caf --- /dev/null +++ b/sdk/database/dbplugin/v5/grpc_client.go @@ -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 +} diff --git a/sdk/database/dbplugin/v5/grpc_client_test.go b/sdk/database/dbplugin/v5/grpc_client_test.go new file mode 100644 index 000000000000..696045c6790a --- /dev/null +++ b/sdk/database/dbplugin/v5/grpc_client_test.go @@ -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 +} diff --git a/sdk/database/dbplugin/v5/grpc_database_plugin.go b/sdk/database/dbplugin/v5/grpc_database_plugin.go new file mode 100644 index 000000000000..24468f72fc45 --- /dev/null +++ b/sdk/database/dbplugin/v5/grpc_database_plugin.go @@ -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 +} diff --git a/sdk/database/dbplugin/v5/grpc_server.go b/sdk/database/dbplugin/v5/grpc_server.go new file mode 100644 index 000000000000..4442c52502e6 --- /dev/null +++ b/sdk/database/dbplugin/v5/grpc_server.go @@ -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 +} diff --git a/sdk/database/dbplugin/v5/grpc_server_test.go b/sdk/database/dbplugin/v5/grpc_server_test.go new file mode 100644 index 000000000000..bd04139f491c --- /dev/null +++ b/sdk/database/dbplugin/v5/grpc_server_test.go @@ -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() +} diff --git a/sdk/database/dbplugin/v5/marshalling.go b/sdk/database/dbplugin/v5/marshalling.go new file mode 100644 index 000000000000..ff8bc7cff7a0 --- /dev/null +++ b/sdk/database/dbplugin/v5/marshalling.go @@ -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 +} diff --git a/sdk/database/dbplugin/v5/middleware.go b/sdk/database/dbplugin/v5/middleware.go new file mode 100644 index 000000000000..20b421206029 --- /dev/null +++ b/sdk/database/dbplugin/v5/middleware.go @@ -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 +} diff --git a/sdk/database/dbplugin/v5/middleware_test.go b/sdk/database/dbplugin/v5/middleware_test.go new file mode 100644 index 000000000000..5dd97cdb9e5a --- /dev/null +++ b/sdk/database/dbplugin/v5/middleware_test.go @@ -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", ""), + expectedError: errors.New("here is my password: iofsd9473tg"), + }, + "secrets that do match": { + inputErr: errors.New("here is my password: iofsd9473tg"), + secretsFunc: secretFunc(t, "iofsd9473tg", ""), + expectedError: errors.New("here is my password: "), + }, + "multiple secrets": { + inputErr: errors.New("here is my password: iofsd9473tg"), + secretsFunc: secretFunc(t, + "iofsd9473tg", "", + "password", "", + ), + expectedError: errors.New("here is my : "), + }, + "gRPC status error": { + inputErr: status.Error(codes.InvalidArgument, "an error with a password iofsd9473tg"), + secretsFunc: secretFunc(t, "iofsd9473tg", ""), + expectedError: status.Errorf(codes.InvalidArgument, "an error with a password "), + }, + } + + 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", ""), + } + + expectedErr := errors.New("password: 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", ""), + } + + expectedErr := errors.New("password: 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", ""), + } + + expectedErr := errors.New("password: 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", ""), + } + + expectedErr := errors.New("password: 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", ""), + } + + expectedErr := errors.New("password: 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", ""), + } + + expectedErr := errors.New("password: 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) + } +} diff --git a/sdk/database/dbplugin/v5/plugin_client.go b/sdk/database/dbplugin/v5/plugin_client.go new file mode 100644 index 000000000000..25caa5e74b7d --- /dev/null +++ b/sdk/database/dbplugin/v5/plugin_client.go @@ -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 +} diff --git a/sdk/database/dbplugin/v5/plugin_factory.go b/sdk/database/dbplugin/v5/plugin_factory.go new file mode 100644 index 000000000000..f203f1ed4cc7 --- /dev/null +++ b/sdk/database/dbplugin/v5/plugin_factory.go @@ -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 +} diff --git a/sdk/database/dbplugin/v5/plugin_server.go b/sdk/database/dbplugin/v5/plugin_server.go new file mode 100644 index 000000000000..e8d09288ad36 --- /dev/null +++ b/sdk/database/dbplugin/v5/plugin_server.go @@ -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 +} diff --git a/sdk/database/newdbplugin/proto/database.pb.go b/sdk/database/dbplugin/v5/proto/database.pb.go similarity index 78% rename from sdk/database/newdbplugin/proto/database.pb.go rename to sdk/database/dbplugin/v5/proto/database.pb.go index b22f1d10a1e3..3bac2143267e 100644 --- a/sdk/database/newdbplugin/proto/database.pb.go +++ b/sdk/database/dbplugin/v5/proto/database.pb.go @@ -2,7 +2,7 @@ // versions: // protoc-gen-go v1.23.0 // protoc v3.13.0 -// source: sdk/database/newdbplugin/proto/database.proto +// source: sdk/database/dbplugin/v5/proto/database.proto package proto @@ -46,7 +46,7 @@ type InitializeRequest struct { func (x *InitializeRequest) Reset() { *x = InitializeRequest{} 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.StoreMessageInfo(mi) } @@ -59,7 +59,7 @@ func (x *InitializeRequest) String() string { func (*InitializeRequest) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -72,7 +72,7 @@ func (x *InitializeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use InitializeRequest.ProtoReflect.Descriptor instead. 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 { @@ -100,7 +100,7 @@ type InitializeResponse struct { func (x *InitializeResponse) Reset() { *x = InitializeResponse{} 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.StoreMessageInfo(mi) } @@ -113,7 +113,7 @@ func (x *InitializeResponse) String() string { func (*InitializeResponse) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -126,7 +126,7 @@ func (x *InitializeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use InitializeResponse.ProtoReflect.Descriptor instead. 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 { @@ -151,7 +151,7 @@ type NewUserRequest struct { func (x *NewUserRequest) Reset() { *x = NewUserRequest{} 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.StoreMessageInfo(mi) } @@ -164,7 +164,7 @@ func (x *NewUserRequest) String() string { func (*NewUserRequest) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -177,7 +177,7 @@ func (x *NewUserRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use NewUserRequest.ProtoReflect.Descriptor instead. 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 { @@ -227,7 +227,7 @@ type UsernameConfig struct { func (x *UsernameConfig) Reset() { *x = UsernameConfig{} 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.StoreMessageInfo(mi) } @@ -240,7 +240,7 @@ func (x *UsernameConfig) String() string { func (*UsernameConfig) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -253,7 +253,7 @@ func (x *UsernameConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use UsernameConfig.ProtoReflect.Descriptor instead. 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 { @@ -281,7 +281,7 @@ type NewUserResponse struct { func (x *NewUserResponse) Reset() { *x = NewUserResponse{} 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.StoreMessageInfo(mi) } @@ -294,7 +294,7 @@ func (x *NewUserResponse) String() string { func (*NewUserResponse) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -307,7 +307,7 @@ func (x *NewUserResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use NewUserResponse.ProtoReflect.Descriptor instead. 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 { @@ -333,7 +333,7 @@ type UpdateUserRequest struct { func (x *UpdateUserRequest) Reset() { *x = UpdateUserRequest{} 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.StoreMessageInfo(mi) } @@ -346,7 +346,7 @@ func (x *UpdateUserRequest) String() string { func (*UpdateUserRequest) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -359,7 +359,7 @@ func (x *UpdateUserRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateUserRequest.ProtoReflect.Descriptor instead. 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 { @@ -395,7 +395,7 @@ type ChangePassword struct { func (x *ChangePassword) Reset() { *x = ChangePassword{} 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.StoreMessageInfo(mi) } @@ -408,7 +408,7 @@ func (x *ChangePassword) String() string { func (*ChangePassword) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -421,7 +421,7 @@ func (x *ChangePassword) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangePassword.ProtoReflect.Descriptor instead. 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 { @@ -450,7 +450,7 @@ type ChangeExpiration struct { func (x *ChangeExpiration) Reset() { *x = ChangeExpiration{} 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.StoreMessageInfo(mi) } @@ -463,7 +463,7 @@ func (x *ChangeExpiration) String() string { func (*ChangeExpiration) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -476,7 +476,7 @@ func (x *ChangeExpiration) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeExpiration.ProtoReflect.Descriptor instead. 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 { @@ -502,7 +502,7 @@ type UpdateUserResponse struct { func (x *UpdateUserResponse) Reset() { *x = UpdateUserResponse{} 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.StoreMessageInfo(mi) } @@ -515,7 +515,7 @@ func (x *UpdateUserResponse) String() string { func (*UpdateUserResponse) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -528,7 +528,7 @@ func (x *UpdateUserResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateUserResponse.ProtoReflect.Descriptor instead. 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() { *x = DeleteUserRequest{} 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.StoreMessageInfo(mi) } @@ -559,7 +559,7 @@ func (x *DeleteUserRequest) String() string { func (*DeleteUserRequest) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -572,7 +572,7 @@ func (x *DeleteUserRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteUserRequest.ProtoReflect.Descriptor instead. 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 { @@ -598,7 +598,7 @@ type DeleteUserResponse struct { func (x *DeleteUserResponse) Reset() { *x = DeleteUserResponse{} 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.StoreMessageInfo(mi) } @@ -611,7 +611,7 @@ func (x *DeleteUserResponse) String() string { func (*DeleteUserResponse) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -624,7 +624,7 @@ func (x *DeleteUserResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteUserResponse.ProtoReflect.Descriptor instead. 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() { *x = TypeResponse{} 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.StoreMessageInfo(mi) } @@ -654,7 +654,7 @@ func (x *TypeResponse) String() string { func (*TypeResponse) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -667,7 +667,7 @@ func (x *TypeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use TypeResponse.ProtoReflect.Descriptor instead. 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 { @@ -691,7 +691,7 @@ type Statements struct { func (x *Statements) Reset() { *x = Statements{} 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.StoreMessageInfo(mi) } @@ -704,7 +704,7 @@ func (x *Statements) String() string { func (*Statements) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -717,7 +717,7 @@ func (x *Statements) ProtoReflect() protoreflect.Message { // Deprecated: Use Statements.ProtoReflect.Descriptor instead. 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 { @@ -736,7 +736,7 @@ type Empty struct { func (x *Empty) Reset() { *x = Empty{} 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.StoreMessageInfo(mi) } @@ -749,7 +749,7 @@ func (x *Empty) String() string { func (*Empty) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -762,16 +762,16 @@ func (x *Empty) ProtoReflect() protoreflect.Message { // Deprecated: Use Empty.ProtoReflect.Descriptor instead. 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{ - 0x0a, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x6e, - 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, +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, 0x64, + 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, - 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, 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, @@ -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, 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, - 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, - 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, + 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, 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, @@ -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, 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, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6e, - 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 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, 0x6d, 0x65, 0x6e, 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, - 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, 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, @@ -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, 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, - 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, 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, - 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x64, 0x62, + 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, 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, 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, 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, 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, @@ -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, 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, - 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, 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, @@ -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, 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, - 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, 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, @@ -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, 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, - 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, - 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, - 0x0a, 0x07, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x6e, 0x65, 0x77, 0x64, - 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 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, - 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x0a, 0x07, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x64, 0x62, 0x70, 0x6c, + 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, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, + 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, - 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, - 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, 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, - 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, - 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x2e, 0x6e, 0x65, 0x77, - 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, - 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x54, 0x79, 0x70, + 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x2e, 0x64, 0x62, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, + 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, - 0x73, 0x65, 0x12, 0x12, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, - 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, + 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, 0x64, 0x62, 0x70, 0x6c, 0x75, 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, 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, - 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x76, + 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_sdk_database_newdbplugin_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_rawDescOnce sync.Once + 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 { - file_sdk_database_newdbplugin_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) +func file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP() []byte { + file_sdk_database_dbplugin_v5_proto_database_proto_rawDescOnce.Do(func() { + 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 -} - -var file_sdk_database_newdbplugin_proto_database_proto_msgTypes = make([]protoimpl.MessageInfo, 14) -var file_sdk_database_newdbplugin_proto_database_proto_goTypes = []interface{}{ - (*InitializeRequest)(nil), // 0: newdbplugin.InitializeRequest - (*InitializeResponse)(nil), // 1: newdbplugin.InitializeResponse - (*NewUserRequest)(nil), // 2: newdbplugin.NewUserRequest - (*UsernameConfig)(nil), // 3: newdbplugin.UsernameConfig - (*NewUserResponse)(nil), // 4: newdbplugin.NewUserResponse - (*UpdateUserRequest)(nil), // 5: newdbplugin.UpdateUserRequest - (*ChangePassword)(nil), // 6: newdbplugin.ChangePassword - (*ChangeExpiration)(nil), // 7: newdbplugin.ChangeExpiration - (*UpdateUserResponse)(nil), // 8: newdbplugin.UpdateUserResponse - (*DeleteUserRequest)(nil), // 9: newdbplugin.DeleteUserRequest - (*DeleteUserResponse)(nil), // 10: newdbplugin.DeleteUserResponse - (*TypeResponse)(nil), // 11: newdbplugin.TypeResponse - (*Statements)(nil), // 12: newdbplugin.Statements - (*Empty)(nil), // 13: newdbplugin.Empty + return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescData +} + +var file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_sdk_database_dbplugin_v5_proto_database_proto_goTypes = []interface{}{ + (*InitializeRequest)(nil), // 0: dbplugin.v5.InitializeRequest + (*InitializeResponse)(nil), // 1: dbplugin.v5.InitializeResponse + (*NewUserRequest)(nil), // 2: dbplugin.v5.NewUserRequest + (*UsernameConfig)(nil), // 3: dbplugin.v5.UsernameConfig + (*NewUserResponse)(nil), // 4: dbplugin.v5.NewUserResponse + (*UpdateUserRequest)(nil), // 5: dbplugin.v5.UpdateUserRequest + (*ChangePassword)(nil), // 6: dbplugin.v5.ChangePassword + (*ChangeExpiration)(nil), // 7: dbplugin.v5.ChangeExpiration + (*UpdateUserResponse)(nil), // 8: dbplugin.v5.UpdateUserResponse + (*DeleteUserRequest)(nil), // 9: dbplugin.v5.DeleteUserRequest + (*DeleteUserResponse)(nil), // 10: dbplugin.v5.DeleteUserResponse + (*TypeResponse)(nil), // 11: dbplugin.v5.TypeResponse + (*Statements)(nil), // 12: dbplugin.v5.Statements + (*Empty)(nil), // 13: dbplugin.v5.Empty (*_struct.Struct)(nil), // 14: google.protobuf.Struct (*timestamp.Timestamp)(nil), // 15: google.protobuf.Timestamp } -var file_sdk_database_newdbplugin_proto_database_proto_depIdxs = []int32{ - 14, // 0: newdbplugin.InitializeRequest.config_data:type_name -> google.protobuf.Struct - 14, // 1: newdbplugin.InitializeResponse.config_data:type_name -> google.protobuf.Struct - 3, // 2: newdbplugin.NewUserRequest.username_config:type_name -> newdbplugin.UsernameConfig - 15, // 3: newdbplugin.NewUserRequest.expiration:type_name -> google.protobuf.Timestamp - 12, // 4: newdbplugin.NewUserRequest.statements:type_name -> newdbplugin.Statements - 12, // 5: newdbplugin.NewUserRequest.rollback_statements:type_name -> newdbplugin.Statements - 6, // 6: newdbplugin.UpdateUserRequest.password:type_name -> newdbplugin.ChangePassword - 7, // 7: newdbplugin.UpdateUserRequest.expiration:type_name -> newdbplugin.ChangeExpiration - 12, // 8: newdbplugin.ChangePassword.statements:type_name -> newdbplugin.Statements - 15, // 9: newdbplugin.ChangeExpiration.new_expiration:type_name -> google.protobuf.Timestamp - 12, // 10: newdbplugin.ChangeExpiration.statements:type_name -> newdbplugin.Statements - 12, // 11: newdbplugin.DeleteUserRequest.statements:type_name -> newdbplugin.Statements - 0, // 12: newdbplugin.Database.Initialize:input_type -> newdbplugin.InitializeRequest - 2, // 13: newdbplugin.Database.NewUser:input_type -> newdbplugin.NewUserRequest - 5, // 14: newdbplugin.Database.UpdateUser:input_type -> newdbplugin.UpdateUserRequest - 9, // 15: newdbplugin.Database.DeleteUser:input_type -> newdbplugin.DeleteUserRequest - 13, // 16: newdbplugin.Database.Type:input_type -> newdbplugin.Empty - 13, // 17: newdbplugin.Database.Close:input_type -> newdbplugin.Empty - 1, // 18: newdbplugin.Database.Initialize:output_type -> newdbplugin.InitializeResponse - 4, // 19: newdbplugin.Database.NewUser:output_type -> newdbplugin.NewUserResponse - 8, // 20: newdbplugin.Database.UpdateUser:output_type -> newdbplugin.UpdateUserResponse - 10, // 21: newdbplugin.Database.DeleteUser:output_type -> newdbplugin.DeleteUserResponse - 11, // 22: newdbplugin.Database.Type:output_type -> newdbplugin.TypeResponse - 13, // 23: newdbplugin.Database.Close:output_type -> newdbplugin.Empty +var file_sdk_database_dbplugin_v5_proto_database_proto_depIdxs = []int32{ + 14, // 0: dbplugin.v5.InitializeRequest.config_data:type_name -> google.protobuf.Struct + 14, // 1: dbplugin.v5.InitializeResponse.config_data:type_name -> google.protobuf.Struct + 3, // 2: dbplugin.v5.NewUserRequest.username_config:type_name -> dbplugin.v5.UsernameConfig + 15, // 3: dbplugin.v5.NewUserRequest.expiration:type_name -> google.protobuf.Timestamp + 12, // 4: dbplugin.v5.NewUserRequest.statements:type_name -> dbplugin.v5.Statements + 12, // 5: dbplugin.v5.NewUserRequest.rollback_statements:type_name -> dbplugin.v5.Statements + 6, // 6: dbplugin.v5.UpdateUserRequest.password:type_name -> dbplugin.v5.ChangePassword + 7, // 7: dbplugin.v5.UpdateUserRequest.expiration:type_name -> dbplugin.v5.ChangeExpiration + 12, // 8: dbplugin.v5.ChangePassword.statements:type_name -> dbplugin.v5.Statements + 15, // 9: dbplugin.v5.ChangeExpiration.new_expiration:type_name -> google.protobuf.Timestamp + 12, // 10: dbplugin.v5.ChangeExpiration.statements:type_name -> dbplugin.v5.Statements + 12, // 11: dbplugin.v5.DeleteUserRequest.statements:type_name -> dbplugin.v5.Statements + 0, // 12: dbplugin.v5.Database.Initialize:input_type -> dbplugin.v5.InitializeRequest + 2, // 13: dbplugin.v5.Database.NewUser:input_type -> dbplugin.v5.NewUserRequest + 5, // 14: dbplugin.v5.Database.UpdateUser:input_type -> dbplugin.v5.UpdateUserRequest + 9, // 15: dbplugin.v5.Database.DeleteUser:input_type -> dbplugin.v5.DeleteUserRequest + 13, // 16: dbplugin.v5.Database.Type:input_type -> dbplugin.v5.Empty + 13, // 17: dbplugin.v5.Database.Close:input_type -> dbplugin.v5.Empty + 1, // 18: dbplugin.v5.Database.Initialize:output_type -> dbplugin.v5.InitializeResponse + 4, // 19: dbplugin.v5.Database.NewUser:output_type -> dbplugin.v5.NewUserResponse + 8, // 20: dbplugin.v5.Database.UpdateUser:output_type -> dbplugin.v5.UpdateUserResponse + 10, // 21: dbplugin.v5.Database.DeleteUser:output_type -> dbplugin.v5.DeleteUserResponse + 11, // 22: dbplugin.v5.Database.Type:output_type -> dbplugin.v5.TypeResponse + 13, // 23: dbplugin.v5.Database.Close:output_type -> dbplugin.v5.Empty 18, // [18:24] is the sub-list for method output_type 12, // [12:18] is the sub-list for method input_type 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 } -func init() { file_sdk_database_newdbplugin_proto_database_proto_init() } -func file_sdk_database_newdbplugin_proto_database_proto_init() { - if File_sdk_database_newdbplugin_proto_database_proto != nil { +func init() { file_sdk_database_dbplugin_v5_proto_database_proto_init() } +func file_sdk_database_dbplugin_v5_proto_database_proto_init() { + if File_sdk_database_dbplugin_v5_proto_database_proto != nil { return } 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 { case 0: return &v.state @@ -971,7 +971,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -983,7 +983,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -995,7 +995,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1007,7 +1007,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1019,7 +1019,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1031,7 +1031,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1043,7 +1043,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1055,7 +1055,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1067,7 +1067,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1079,7 +1079,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1091,7 +1091,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1103,7 +1103,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1115,7 +1115,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1132,20 +1132,20 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ 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, NumMessages: 14, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_sdk_database_newdbplugin_proto_database_proto_goTypes, - DependencyIndexes: file_sdk_database_newdbplugin_proto_database_proto_depIdxs, - MessageInfos: file_sdk_database_newdbplugin_proto_database_proto_msgTypes, + GoTypes: file_sdk_database_dbplugin_v5_proto_database_proto_goTypes, + DependencyIndexes: file_sdk_database_dbplugin_v5_proto_database_proto_depIdxs, + MessageInfos: file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes, }.Build() - File_sdk_database_newdbplugin_proto_database_proto = out.File - file_sdk_database_newdbplugin_proto_database_proto_rawDesc = nil - file_sdk_database_newdbplugin_proto_database_proto_goTypes = nil - file_sdk_database_newdbplugin_proto_database_proto_depIdxs = nil + File_sdk_database_dbplugin_v5_proto_database_proto = out.File + file_sdk_database_dbplugin_v5_proto_database_proto_rawDesc = nil + file_sdk_database_dbplugin_v5_proto_database_proto_goTypes = nil + file_sdk_database_dbplugin_v5_proto_database_proto_depIdxs = nil } // 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) { 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 { 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) { 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 { 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) { 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 { 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) { 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 { 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) { 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 { 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) { 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 { return nil, err } @@ -1277,7 +1277,7 @@ func _Database_Initialize_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/newdbplugin.Database/Initialize", + FullMethod: "/dbplugin.v5.Database/Initialize", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ Server: srv, - FullMethod: "/newdbplugin.Database/NewUser", + FullMethod: "/dbplugin.v5.Database/NewUser", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ Server: srv, - FullMethod: "/newdbplugin.Database/UpdateUser", + FullMethod: "/dbplugin.v5.Database/UpdateUser", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ Server: srv, - FullMethod: "/newdbplugin.Database/DeleteUser", + FullMethod: "/dbplugin.v5.Database/DeleteUser", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ Server: srv, - FullMethod: "/newdbplugin.Database/Type", + FullMethod: "/dbplugin.v5.Database/Type", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ Server: srv, - FullMethod: "/newdbplugin.Database/Close", + FullMethod: "/dbplugin.v5.Database/Close", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ - ServiceName: "newdbplugin.Database", + ServiceName: "dbplugin.v5.Database", HandlerType: (*DatabaseServer)(nil), Methods: []grpc.MethodDesc{ { @@ -1405,5 +1405,5 @@ var _Database_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "sdk/database/newdbplugin/proto/database.proto", + Metadata: "sdk/database/dbplugin/v5/proto/database.proto", } diff --git a/sdk/database/newdbplugin/proto/database.proto b/sdk/database/dbplugin/v5/proto/database.proto similarity index 93% rename from sdk/database/newdbplugin/proto/database.proto rename to sdk/database/dbplugin/v5/proto/database.proto index 74eb4f670170..be38548eec4c 100644 --- a/sdk/database/newdbplugin/proto/database.proto +++ b/sdk/database/dbplugin/v5/proto/database.proto @@ -1,7 +1,7 @@ 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/timestamp.proto"; diff --git a/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/testing/test_helpers.go b/sdk/database/dbplugin/v5/testing/test_helpers.go similarity index 72% rename from vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/testing/test_helpers.go rename to sdk/database/dbplugin/v5/testing/test_helpers.go index 05e8d8f9b789..200a603649a3 100644 --- a/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/testing/test_helpers.go +++ b/sdk/database/dbplugin/v5/testing/test_helpers.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/hashicorp/vault/sdk/database/newdbplugin" + "github.com/hashicorp/vault/sdk/database/dbplugin/v5" ) func getRequestTimeout(t *testing.T) time.Duration { @@ -22,7 +22,7 @@ func getRequestTimeout(t *testing.T) time.Duration { 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() 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 } -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() 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 } -func AssertUpdateUser(t *testing.T, db newdbplugin.Database, req newdbplugin.UpdateUserRequest) { +func AssertUpdateUser(t *testing.T, db dbplugin.Database, req dbplugin.UpdateUserRequest) { t.Helper() 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() 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() err := db.Close() if err != nil { diff --git a/sdk/database/newdbplugin/conversions_test.go b/sdk/database/newdbplugin/conversions_test.go index 6b4dc27a35a6..cd931c18f655 100644 --- a/sdk/database/newdbplugin/conversions_test.go +++ b/sdk/database/newdbplugin/conversions_test.go @@ -8,7 +8,7 @@ import ( "time" "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/timestamppb" diff --git a/sdk/database/newdbplugin/grpc_client.go b/sdk/database/newdbplugin/grpc_client.go index 2d51d2e04d27..ceb206a98131 100644 --- a/sdk/database/newdbplugin/grpc_client.go +++ b/sdk/database/newdbplugin/grpc_client.go @@ -7,7 +7,7 @@ import ( "time" "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" ) diff --git a/sdk/database/newdbplugin/grpc_client_test.go b/sdk/database/newdbplugin/grpc_client_test.go index 04a6c6744f02..50313ba57549 100644 --- a/sdk/database/newdbplugin/grpc_client_test.go +++ b/sdk/database/newdbplugin/grpc_client_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/hashicorp/vault/sdk/database/newdbplugin/proto" + "github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" "google.golang.org/grpc" ) diff --git a/sdk/database/newdbplugin/grpc_database_plugin.go b/sdk/database/newdbplugin/grpc_database_plugin.go index 66468640ce58..23e6bc3b5c57 100644 --- a/sdk/database/newdbplugin/grpc_database_plugin.go +++ b/sdk/database/newdbplugin/grpc_database_plugin.go @@ -4,7 +4,7 @@ import ( "context" "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" ) diff --git a/sdk/database/newdbplugin/grpc_server.go b/sdk/database/newdbplugin/grpc_server.go index 646e894ed3ee..f9dd959124b8 100644 --- a/sdk/database/newdbplugin/grpc_server.go +++ b/sdk/database/newdbplugin/grpc_server.go @@ -6,7 +6,7 @@ import ( "time" "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/status" ) diff --git a/sdk/database/newdbplugin/grpc_server_test.go b/sdk/database/newdbplugin/grpc_server_test.go index eade8a781ec6..72176099943f 100644 --- a/sdk/database/newdbplugin/grpc_server_test.go +++ b/sdk/database/newdbplugin/grpc_server_test.go @@ -12,7 +12,7 @@ import ( "github.com/golang/protobuf/ptypes" "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/status" ) diff --git a/sdk/database/newdbplugin/testing/test_helpers.go b/sdk/database/newdbplugin/testing/test_helpers.go index 05e8d8f9b789..200a603649a3 100644 --- a/sdk/database/newdbplugin/testing/test_helpers.go +++ b/sdk/database/newdbplugin/testing/test_helpers.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/hashicorp/vault/sdk/database/newdbplugin" + "github.com/hashicorp/vault/sdk/database/dbplugin/v5" ) func getRequestTimeout(t *testing.T) time.Duration { @@ -22,7 +22,7 @@ func getRequestTimeout(t *testing.T) time.Duration { 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() 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 } -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() 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 } -func AssertUpdateUser(t *testing.T, db newdbplugin.Database, req newdbplugin.UpdateUserRequest) { +func AssertUpdateUser(t *testing.T, db dbplugin.Database, req dbplugin.UpdateUserRequest) { t.Helper() 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() 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() err := db.Close() if err != nil { diff --git a/vault/plugin_catalog.go b/vault/plugin_catalog.go index 47f7c6f8bf45..47c6fdbf326c 100644 --- a/vault/plugin_catalog.go +++ b/vault/plugin_catalog.go @@ -13,8 +13,8 @@ import ( "github.com/hashicorp/errwrap" log "github.com/hashicorp/go-hclog" multierror "github.com/hashicorp/go-multierror" - "github.com/hashicorp/vault/sdk/database/dbplugin" - "github.com/hashicorp/vault/sdk/database/newdbplugin" + v4 "github.com/hashicorp/vault/sdk/database/dbplugin" + v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" "github.com/hashicorp/vault/sdk/helper/consts" "github.com/hashicorp/vault/sdk/helper/jsonutil" "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 { merr := &multierror.Error{} // 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 { // Close the client and cleanup the plugin process 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)) - v4Client, err := dbplugin.NewPluginClient(ctx, nil, plugin, log.NewNullLogger(), true) + v4Client, err := v4.NewPluginClient(ctx, nil, plugin, log.NewNullLogger(), true) if err == nil { // Close the client and cleanup the plugin process v4Client.Close() diff --git a/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/database.go b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/database.go new file mode 100644 index 000000000000..225e94280a36 --- /dev/null +++ b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/database.go @@ -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 +} diff --git a/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_client.go b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_client.go new file mode 100644 index 000000000000..47bb1d0a3caf --- /dev/null +++ b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_client.go @@ -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 +} diff --git a/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_database_plugin.go b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_database_plugin.go new file mode 100644 index 000000000000..24468f72fc45 --- /dev/null +++ b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_database_plugin.go @@ -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 +} diff --git a/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_server.go b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_server.go new file mode 100644 index 000000000000..4442c52502e6 --- /dev/null +++ b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/grpc_server.go @@ -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 +} diff --git a/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/marshalling.go b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/marshalling.go new file mode 100644 index 000000000000..ff8bc7cff7a0 --- /dev/null +++ b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/marshalling.go @@ -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 +} diff --git a/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/middleware.go b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/middleware.go new file mode 100644 index 000000000000..20b421206029 --- /dev/null +++ b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/middleware.go @@ -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 +} diff --git a/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_client.go b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_client.go new file mode 100644 index 000000000000..25caa5e74b7d --- /dev/null +++ b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_client.go @@ -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 +} diff --git a/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_factory.go b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_factory.go new file mode 100644 index 000000000000..f203f1ed4cc7 --- /dev/null +++ b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_factory.go @@ -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 +} diff --git a/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_server.go b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_server.go new file mode 100644 index 000000000000..e8d09288ad36 --- /dev/null +++ b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/plugin_server.go @@ -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 +} diff --git a/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/proto/database.pb.go b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto/database.pb.go similarity index 78% rename from vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/proto/database.pb.go rename to vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto/database.pb.go index b22f1d10a1e3..3bac2143267e 100644 --- a/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/proto/database.pb.go +++ b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto/database.pb.go @@ -2,7 +2,7 @@ // versions: // protoc-gen-go v1.23.0 // protoc v3.13.0 -// source: sdk/database/newdbplugin/proto/database.proto +// source: sdk/database/dbplugin/v5/proto/database.proto package proto @@ -46,7 +46,7 @@ type InitializeRequest struct { func (x *InitializeRequest) Reset() { *x = InitializeRequest{} 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.StoreMessageInfo(mi) } @@ -59,7 +59,7 @@ func (x *InitializeRequest) String() string { func (*InitializeRequest) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -72,7 +72,7 @@ func (x *InitializeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use InitializeRequest.ProtoReflect.Descriptor instead. 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 { @@ -100,7 +100,7 @@ type InitializeResponse struct { func (x *InitializeResponse) Reset() { *x = InitializeResponse{} 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.StoreMessageInfo(mi) } @@ -113,7 +113,7 @@ func (x *InitializeResponse) String() string { func (*InitializeResponse) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -126,7 +126,7 @@ func (x *InitializeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use InitializeResponse.ProtoReflect.Descriptor instead. 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 { @@ -151,7 +151,7 @@ type NewUserRequest struct { func (x *NewUserRequest) Reset() { *x = NewUserRequest{} 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.StoreMessageInfo(mi) } @@ -164,7 +164,7 @@ func (x *NewUserRequest) String() string { func (*NewUserRequest) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -177,7 +177,7 @@ func (x *NewUserRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use NewUserRequest.ProtoReflect.Descriptor instead. 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 { @@ -227,7 +227,7 @@ type UsernameConfig struct { func (x *UsernameConfig) Reset() { *x = UsernameConfig{} 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.StoreMessageInfo(mi) } @@ -240,7 +240,7 @@ func (x *UsernameConfig) String() string { func (*UsernameConfig) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -253,7 +253,7 @@ func (x *UsernameConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use UsernameConfig.ProtoReflect.Descriptor instead. 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 { @@ -281,7 +281,7 @@ type NewUserResponse struct { func (x *NewUserResponse) Reset() { *x = NewUserResponse{} 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.StoreMessageInfo(mi) } @@ -294,7 +294,7 @@ func (x *NewUserResponse) String() string { func (*NewUserResponse) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -307,7 +307,7 @@ func (x *NewUserResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use NewUserResponse.ProtoReflect.Descriptor instead. 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 { @@ -333,7 +333,7 @@ type UpdateUserRequest struct { func (x *UpdateUserRequest) Reset() { *x = UpdateUserRequest{} 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.StoreMessageInfo(mi) } @@ -346,7 +346,7 @@ func (x *UpdateUserRequest) String() string { func (*UpdateUserRequest) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -359,7 +359,7 @@ func (x *UpdateUserRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateUserRequest.ProtoReflect.Descriptor instead. 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 { @@ -395,7 +395,7 @@ type ChangePassword struct { func (x *ChangePassword) Reset() { *x = ChangePassword{} 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.StoreMessageInfo(mi) } @@ -408,7 +408,7 @@ func (x *ChangePassword) String() string { func (*ChangePassword) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -421,7 +421,7 @@ func (x *ChangePassword) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangePassword.ProtoReflect.Descriptor instead. 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 { @@ -450,7 +450,7 @@ type ChangeExpiration struct { func (x *ChangeExpiration) Reset() { *x = ChangeExpiration{} 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.StoreMessageInfo(mi) } @@ -463,7 +463,7 @@ func (x *ChangeExpiration) String() string { func (*ChangeExpiration) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -476,7 +476,7 @@ func (x *ChangeExpiration) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeExpiration.ProtoReflect.Descriptor instead. 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 { @@ -502,7 +502,7 @@ type UpdateUserResponse struct { func (x *UpdateUserResponse) Reset() { *x = UpdateUserResponse{} 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.StoreMessageInfo(mi) } @@ -515,7 +515,7 @@ func (x *UpdateUserResponse) String() string { func (*UpdateUserResponse) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -528,7 +528,7 @@ func (x *UpdateUserResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateUserResponse.ProtoReflect.Descriptor instead. 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() { *x = DeleteUserRequest{} 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.StoreMessageInfo(mi) } @@ -559,7 +559,7 @@ func (x *DeleteUserRequest) String() string { func (*DeleteUserRequest) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -572,7 +572,7 @@ func (x *DeleteUserRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteUserRequest.ProtoReflect.Descriptor instead. 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 { @@ -598,7 +598,7 @@ type DeleteUserResponse struct { func (x *DeleteUserResponse) Reset() { *x = DeleteUserResponse{} 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.StoreMessageInfo(mi) } @@ -611,7 +611,7 @@ func (x *DeleteUserResponse) String() string { func (*DeleteUserResponse) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -624,7 +624,7 @@ func (x *DeleteUserResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteUserResponse.ProtoReflect.Descriptor instead. 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() { *x = TypeResponse{} 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.StoreMessageInfo(mi) } @@ -654,7 +654,7 @@ func (x *TypeResponse) String() string { func (*TypeResponse) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -667,7 +667,7 @@ func (x *TypeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use TypeResponse.ProtoReflect.Descriptor instead. 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 { @@ -691,7 +691,7 @@ type Statements struct { func (x *Statements) Reset() { *x = Statements{} 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.StoreMessageInfo(mi) } @@ -704,7 +704,7 @@ func (x *Statements) String() string { func (*Statements) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -717,7 +717,7 @@ func (x *Statements) ProtoReflect() protoreflect.Message { // Deprecated: Use Statements.ProtoReflect.Descriptor instead. 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 { @@ -736,7 +736,7 @@ type Empty struct { func (x *Empty) Reset() { *x = Empty{} 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.StoreMessageInfo(mi) } @@ -749,7 +749,7 @@ func (x *Empty) String() string { func (*Empty) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -762,16 +762,16 @@ func (x *Empty) ProtoReflect() protoreflect.Message { // Deprecated: Use Empty.ProtoReflect.Descriptor instead. 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{ - 0x0a, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x6e, - 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, +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, 0x64, + 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, - 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, 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, @@ -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, 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, - 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, - 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, + 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, 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, @@ -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, 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, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6e, - 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 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, 0x6d, 0x65, 0x6e, 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, - 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, 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, @@ -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, 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, - 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, 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, - 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x64, 0x62, + 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, 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, 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, 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, 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, @@ -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, 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, - 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, 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, @@ -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, 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, - 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, 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, @@ -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, 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, - 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, - 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, - 0x0a, 0x07, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x6e, 0x65, 0x77, 0x64, - 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 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, - 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x0a, 0x07, 0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x64, 0x62, 0x70, 0x6c, + 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, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, + 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, - 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, - 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, 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, - 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, - 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x2e, 0x6e, 0x65, 0x77, - 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, - 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x54, 0x79, 0x70, + 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x2e, 0x64, 0x62, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x35, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, + 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, - 0x73, 0x65, 0x12, 0x12, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x6e, 0x65, 0x77, 0x64, 0x62, 0x70, 0x6c, - 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, + 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, 0x64, 0x62, 0x70, 0x6c, 0x75, 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, 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, - 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x64, 0x62, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x76, + 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_sdk_database_newdbplugin_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_rawDescOnce sync.Once + 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 { - file_sdk_database_newdbplugin_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) +func file_sdk_database_dbplugin_v5_proto_database_proto_rawDescGZIP() []byte { + file_sdk_database_dbplugin_v5_proto_database_proto_rawDescOnce.Do(func() { + 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 -} - -var file_sdk_database_newdbplugin_proto_database_proto_msgTypes = make([]protoimpl.MessageInfo, 14) -var file_sdk_database_newdbplugin_proto_database_proto_goTypes = []interface{}{ - (*InitializeRequest)(nil), // 0: newdbplugin.InitializeRequest - (*InitializeResponse)(nil), // 1: newdbplugin.InitializeResponse - (*NewUserRequest)(nil), // 2: newdbplugin.NewUserRequest - (*UsernameConfig)(nil), // 3: newdbplugin.UsernameConfig - (*NewUserResponse)(nil), // 4: newdbplugin.NewUserResponse - (*UpdateUserRequest)(nil), // 5: newdbplugin.UpdateUserRequest - (*ChangePassword)(nil), // 6: newdbplugin.ChangePassword - (*ChangeExpiration)(nil), // 7: newdbplugin.ChangeExpiration - (*UpdateUserResponse)(nil), // 8: newdbplugin.UpdateUserResponse - (*DeleteUserRequest)(nil), // 9: newdbplugin.DeleteUserRequest - (*DeleteUserResponse)(nil), // 10: newdbplugin.DeleteUserResponse - (*TypeResponse)(nil), // 11: newdbplugin.TypeResponse - (*Statements)(nil), // 12: newdbplugin.Statements - (*Empty)(nil), // 13: newdbplugin.Empty + return file_sdk_database_dbplugin_v5_proto_database_proto_rawDescData +} + +var file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_sdk_database_dbplugin_v5_proto_database_proto_goTypes = []interface{}{ + (*InitializeRequest)(nil), // 0: dbplugin.v5.InitializeRequest + (*InitializeResponse)(nil), // 1: dbplugin.v5.InitializeResponse + (*NewUserRequest)(nil), // 2: dbplugin.v5.NewUserRequest + (*UsernameConfig)(nil), // 3: dbplugin.v5.UsernameConfig + (*NewUserResponse)(nil), // 4: dbplugin.v5.NewUserResponse + (*UpdateUserRequest)(nil), // 5: dbplugin.v5.UpdateUserRequest + (*ChangePassword)(nil), // 6: dbplugin.v5.ChangePassword + (*ChangeExpiration)(nil), // 7: dbplugin.v5.ChangeExpiration + (*UpdateUserResponse)(nil), // 8: dbplugin.v5.UpdateUserResponse + (*DeleteUserRequest)(nil), // 9: dbplugin.v5.DeleteUserRequest + (*DeleteUserResponse)(nil), // 10: dbplugin.v5.DeleteUserResponse + (*TypeResponse)(nil), // 11: dbplugin.v5.TypeResponse + (*Statements)(nil), // 12: dbplugin.v5.Statements + (*Empty)(nil), // 13: dbplugin.v5.Empty (*_struct.Struct)(nil), // 14: google.protobuf.Struct (*timestamp.Timestamp)(nil), // 15: google.protobuf.Timestamp } -var file_sdk_database_newdbplugin_proto_database_proto_depIdxs = []int32{ - 14, // 0: newdbplugin.InitializeRequest.config_data:type_name -> google.protobuf.Struct - 14, // 1: newdbplugin.InitializeResponse.config_data:type_name -> google.protobuf.Struct - 3, // 2: newdbplugin.NewUserRequest.username_config:type_name -> newdbplugin.UsernameConfig - 15, // 3: newdbplugin.NewUserRequest.expiration:type_name -> google.protobuf.Timestamp - 12, // 4: newdbplugin.NewUserRequest.statements:type_name -> newdbplugin.Statements - 12, // 5: newdbplugin.NewUserRequest.rollback_statements:type_name -> newdbplugin.Statements - 6, // 6: newdbplugin.UpdateUserRequest.password:type_name -> newdbplugin.ChangePassword - 7, // 7: newdbplugin.UpdateUserRequest.expiration:type_name -> newdbplugin.ChangeExpiration - 12, // 8: newdbplugin.ChangePassword.statements:type_name -> newdbplugin.Statements - 15, // 9: newdbplugin.ChangeExpiration.new_expiration:type_name -> google.protobuf.Timestamp - 12, // 10: newdbplugin.ChangeExpiration.statements:type_name -> newdbplugin.Statements - 12, // 11: newdbplugin.DeleteUserRequest.statements:type_name -> newdbplugin.Statements - 0, // 12: newdbplugin.Database.Initialize:input_type -> newdbplugin.InitializeRequest - 2, // 13: newdbplugin.Database.NewUser:input_type -> newdbplugin.NewUserRequest - 5, // 14: newdbplugin.Database.UpdateUser:input_type -> newdbplugin.UpdateUserRequest - 9, // 15: newdbplugin.Database.DeleteUser:input_type -> newdbplugin.DeleteUserRequest - 13, // 16: newdbplugin.Database.Type:input_type -> newdbplugin.Empty - 13, // 17: newdbplugin.Database.Close:input_type -> newdbplugin.Empty - 1, // 18: newdbplugin.Database.Initialize:output_type -> newdbplugin.InitializeResponse - 4, // 19: newdbplugin.Database.NewUser:output_type -> newdbplugin.NewUserResponse - 8, // 20: newdbplugin.Database.UpdateUser:output_type -> newdbplugin.UpdateUserResponse - 10, // 21: newdbplugin.Database.DeleteUser:output_type -> newdbplugin.DeleteUserResponse - 11, // 22: newdbplugin.Database.Type:output_type -> newdbplugin.TypeResponse - 13, // 23: newdbplugin.Database.Close:output_type -> newdbplugin.Empty +var file_sdk_database_dbplugin_v5_proto_database_proto_depIdxs = []int32{ + 14, // 0: dbplugin.v5.InitializeRequest.config_data:type_name -> google.protobuf.Struct + 14, // 1: dbplugin.v5.InitializeResponse.config_data:type_name -> google.protobuf.Struct + 3, // 2: dbplugin.v5.NewUserRequest.username_config:type_name -> dbplugin.v5.UsernameConfig + 15, // 3: dbplugin.v5.NewUserRequest.expiration:type_name -> google.protobuf.Timestamp + 12, // 4: dbplugin.v5.NewUserRequest.statements:type_name -> dbplugin.v5.Statements + 12, // 5: dbplugin.v5.NewUserRequest.rollback_statements:type_name -> dbplugin.v5.Statements + 6, // 6: dbplugin.v5.UpdateUserRequest.password:type_name -> dbplugin.v5.ChangePassword + 7, // 7: dbplugin.v5.UpdateUserRequest.expiration:type_name -> dbplugin.v5.ChangeExpiration + 12, // 8: dbplugin.v5.ChangePassword.statements:type_name -> dbplugin.v5.Statements + 15, // 9: dbplugin.v5.ChangeExpiration.new_expiration:type_name -> google.protobuf.Timestamp + 12, // 10: dbplugin.v5.ChangeExpiration.statements:type_name -> dbplugin.v5.Statements + 12, // 11: dbplugin.v5.DeleteUserRequest.statements:type_name -> dbplugin.v5.Statements + 0, // 12: dbplugin.v5.Database.Initialize:input_type -> dbplugin.v5.InitializeRequest + 2, // 13: dbplugin.v5.Database.NewUser:input_type -> dbplugin.v5.NewUserRequest + 5, // 14: dbplugin.v5.Database.UpdateUser:input_type -> dbplugin.v5.UpdateUserRequest + 9, // 15: dbplugin.v5.Database.DeleteUser:input_type -> dbplugin.v5.DeleteUserRequest + 13, // 16: dbplugin.v5.Database.Type:input_type -> dbplugin.v5.Empty + 13, // 17: dbplugin.v5.Database.Close:input_type -> dbplugin.v5.Empty + 1, // 18: dbplugin.v5.Database.Initialize:output_type -> dbplugin.v5.InitializeResponse + 4, // 19: dbplugin.v5.Database.NewUser:output_type -> dbplugin.v5.NewUserResponse + 8, // 20: dbplugin.v5.Database.UpdateUser:output_type -> dbplugin.v5.UpdateUserResponse + 10, // 21: dbplugin.v5.Database.DeleteUser:output_type -> dbplugin.v5.DeleteUserResponse + 11, // 22: dbplugin.v5.Database.Type:output_type -> dbplugin.v5.TypeResponse + 13, // 23: dbplugin.v5.Database.Close:output_type -> dbplugin.v5.Empty 18, // [18:24] is the sub-list for method output_type 12, // [12:18] is the sub-list for method input_type 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 } -func init() { file_sdk_database_newdbplugin_proto_database_proto_init() } -func file_sdk_database_newdbplugin_proto_database_proto_init() { - if File_sdk_database_newdbplugin_proto_database_proto != nil { +func init() { file_sdk_database_dbplugin_v5_proto_database_proto_init() } +func file_sdk_database_dbplugin_v5_proto_database_proto_init() { + if File_sdk_database_dbplugin_v5_proto_database_proto != nil { return } 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 { case 0: return &v.state @@ -971,7 +971,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -983,7 +983,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -995,7 +995,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1007,7 +1007,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1019,7 +1019,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1031,7 +1031,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1043,7 +1043,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1055,7 +1055,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1067,7 +1067,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1079,7 +1079,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1091,7 +1091,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1103,7 +1103,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1115,7 +1115,7 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { 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 { case 0: return &v.state @@ -1132,20 +1132,20 @@ func file_sdk_database_newdbplugin_proto_database_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ 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, NumMessages: 14, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_sdk_database_newdbplugin_proto_database_proto_goTypes, - DependencyIndexes: file_sdk_database_newdbplugin_proto_database_proto_depIdxs, - MessageInfos: file_sdk_database_newdbplugin_proto_database_proto_msgTypes, + GoTypes: file_sdk_database_dbplugin_v5_proto_database_proto_goTypes, + DependencyIndexes: file_sdk_database_dbplugin_v5_proto_database_proto_depIdxs, + MessageInfos: file_sdk_database_dbplugin_v5_proto_database_proto_msgTypes, }.Build() - File_sdk_database_newdbplugin_proto_database_proto = out.File - file_sdk_database_newdbplugin_proto_database_proto_rawDesc = nil - file_sdk_database_newdbplugin_proto_database_proto_goTypes = nil - file_sdk_database_newdbplugin_proto_database_proto_depIdxs = nil + File_sdk_database_dbplugin_v5_proto_database_proto = out.File + file_sdk_database_dbplugin_v5_proto_database_proto_rawDesc = nil + file_sdk_database_dbplugin_v5_proto_database_proto_goTypes = nil + file_sdk_database_dbplugin_v5_proto_database_proto_depIdxs = nil } // 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) { 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 { 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) { 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 { 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) { 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 { 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) { 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 { 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) { 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 { 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) { 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 { return nil, err } @@ -1277,7 +1277,7 @@ func _Database_Initialize_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/newdbplugin.Database/Initialize", + FullMethod: "/dbplugin.v5.Database/Initialize", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ Server: srv, - FullMethod: "/newdbplugin.Database/NewUser", + FullMethod: "/dbplugin.v5.Database/NewUser", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ Server: srv, - FullMethod: "/newdbplugin.Database/UpdateUser", + FullMethod: "/dbplugin.v5.Database/UpdateUser", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ Server: srv, - FullMethod: "/newdbplugin.Database/DeleteUser", + FullMethod: "/dbplugin.v5.Database/DeleteUser", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ Server: srv, - FullMethod: "/newdbplugin.Database/Type", + FullMethod: "/dbplugin.v5.Database/Type", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ Server: srv, - FullMethod: "/newdbplugin.Database/Close", + FullMethod: "/dbplugin.v5.Database/Close", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ - ServiceName: "newdbplugin.Database", + ServiceName: "dbplugin.v5.Database", HandlerType: (*DatabaseServer)(nil), Methods: []grpc.MethodDesc{ { @@ -1405,5 +1405,5 @@ var _Database_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "sdk/database/newdbplugin/proto/database.proto", + Metadata: "sdk/database/dbplugin/v5/proto/database.proto", } diff --git a/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/proto/database.proto b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto/database.proto similarity index 93% rename from vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/proto/database.proto rename to vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto/database.proto index 74eb4f670170..be38548eec4c 100644 --- a/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/proto/database.proto +++ b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto/database.proto @@ -1,7 +1,7 @@ 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/timestamp.proto"; diff --git a/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/testing/test_helpers.go b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/testing/test_helpers.go new file mode 100644 index 000000000000..200a603649a3 --- /dev/null +++ b/vendor/github.com/hashicorp/vault/sdk/database/dbplugin/v5/testing/test_helpers.go @@ -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) + } +} diff --git a/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_client.go b/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_client.go index 2d51d2e04d27..ceb206a98131 100644 --- a/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_client.go +++ b/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_client.go @@ -7,7 +7,7 @@ import ( "time" "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" ) diff --git a/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_database_plugin.go b/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_database_plugin.go index 66468640ce58..23e6bc3b5c57 100644 --- a/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_database_plugin.go +++ b/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_database_plugin.go @@ -4,7 +4,7 @@ import ( "context" "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" ) diff --git a/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_server.go b/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_server.go index 646e894ed3ee..f9dd959124b8 100644 --- a/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_server.go +++ b/vendor/github.com/hashicorp/vault/sdk/database/newdbplugin/grpc_server.go @@ -6,7 +6,7 @@ import ( "time" "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/status" ) diff --git a/vendor/modules.txt b/vendor/modules.txt index aa672ac08d46..b4f93aa945ba 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -553,12 +553,13 @@ github.com/hashicorp/vault-plugin-secrets-openldap/client github.com/hashicorp/vault/api # 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/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/credsutil github.com/hashicorp/vault/sdk/database/helper/dbutil 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/helper/authmetadata github.com/hashicorp/vault/sdk/helper/awsutil