* enable registering backend muxed plugins in plugin catalog * set the sysview on the pluginconfig to allow enabling secrets/auth plugins * store backend instances in map * store single implementations in the instances map cleanup instance map and ensure we don't deadlock * fix system backend unit tests move GetMultiplexIDFromContext to pluginutil package fix pluginutil test fix dbplugin ut * return error(s) if we can't get the plugin client update comments * refactor/move GetMultiplexIDFromContext test * add changelog * remove unnecessary field on pluginClient * add unit tests to PluginCatalog for secrets/auth plugins * fix comment * return pluginClient from TestRunTestPlugin * add multiplexed backend test * honor metadatamode value in newbackend pluginconfig * check that connection exists on cleanup * add automtls to secrets/auth plugins * don't remove apiclientmeta parsing * use formatting directive for fmt.Errorf * fix ut: remove tls provider func * remove tlsproviderfunc from backend plugin tests * use env var to prevent test plugin from running as a unit test * WIP: remove lazy loading * move non lazy loaded backend to new package * use version wrapper for backend plugin factory * remove backendVersionWrapper type * implement getBackendPluginType for plugin catalog * handle backend plugin v4 registration * add plugin automtls env guard * modify plugin factory to determine the backend to use * remove old pluginsets from v5 and log pid in plugin catalog * add reload mechanism via context * readd v3 and v4 to pluginset * call cleanup from reload if non-muxed * move v5 backend code to new package * use context reload for for ErrPluginShutdown case * add wrapper on v5 backend * fix run config UTs * fix unit tests - use v4/v5 mapping for plugin versions - fix test build err - add reload method on fakePluginClient - add multiplexed cases for integration tests * remove comment and update AutoMTLS field in test * remove comment * remove errwrap and unused context * only support metadatamode false for v5 backend plugins * update plugin catalog errors * use const for env variables * rename locks and remove unused * remove unneeded nil check * improvements based on staticcheck recommendations * use const for single implementation string * use const for context key * use info default log level * move pid to pluginClient struct * remove v3 and v4 from multiplexed plugin set * return from reload when non-multiplexed * update automtls env string * combine getBackend and getBrokeredClient * update comments for plugin reload, Backend return val and log * revert Backend return type * allow non-muxed plugins to serve v5 * move v5 code to existing sdk plugin package * do next export sdk fields now that we have removed extra plugin pkg * set TLSProvider in ServeMultiplex for backwards compat * use bool to flag multiplexing support on grpc backend server * revert userpass main.go * refactor plugin sdk - update comments - make use of multiplexing boolean and single implementation ID const * update comment and use multierr * attempt v4 if dispense fails on getPluginTypeForUnknown * update comments on sdk plugin backend
Combined Database Engine
This package is how database plugins interact with Vault.
Upgrading to Version 5
Background
In Vault 1.6, a new Database interface was created that solved a number of issues with the previous interface:
- It could not use password policies because the database plugins were responsible for generating passwords.
- There were significant inconsistencies between functions in the interface.
- Several functions (
SetCredentialsandRotateRootCredentials) were doing the same operation. - It had a function that was no longer being used as it had been deprecated in a previous version but never removed.
Prior to Vault 1.6, the Database interface is version 4 (with other versions in older versions of Vault). The new version introduced in Vault 1.6 is version 5. This distinction was not exposed in previous iterations of the Database interface as the previous versions were additive to the interface. Since version 5 is an overhaul of the interface, this distinction needed to be made.
We highly recommend that you upgrade any version 4 database plugins to version 5 as version 4 is considered deprecated and support for it will be removed in a future release. Version 5 plugins will not function with Vault prior to Vault 1.6.
The new interface is roughly modeled after a gRPC interface. It has improved future compatibility by not requiring changes to the interface definition to add additional data in the requests or responses. It also simplifies the interface by merging several into a single function call.
Upgrading your custom database
Vault 1.6 supports both version 4 and version 5 database plugins. The support for version 4 plugins will be removed in a future release. Version 5 database plugins will not function with Vault prior to version 1.6. If you upgrade your database plugins, ensure that you are only using Vault 1.6 or later. To determine if a plugin is using version 4 or version 5, the following is a list of changes in no particular order that you can check against your plugin to determine the version:
- The import path for version 4 is
github.com/hashicorp/vault/sdk/database/dbpluginwhereas the import path for version 5 isgithub.com/hashicorp/vault/sdk/database/dbplugin/v5 - Version 4 has the following functions:
Initialize,Init,CreateUser,RenewUser,RevokeUser,SetCredentials,RotateRootCredentials,Type, andClose. You can see the full function signatures insdk/database/dbplugin/plugin.go. - Version 5 has the following functions:
Initialize,NewUser,UpdateUser,DeleteUser,Type, andClose. You can see the full function signatures insdk/database/dbplugin/v5/database.go.
If you are using a version 4 custom database plugin, the following are basic instructions for upgrading to version 5.
-> In version 4, password generation was the responsibility of the plugin. This is no longer
the case with version 5. Vault is responsible for generating passwords and passing them to
the plugin via NewUserRequest.Password and UpdateUserRequest.Password.NewPassword.
- Change the import path from
github.com/hashicorp/vault/sdk/database/dbplugintogithub.com/hashicorp/vault/sdk/database/dbplugin/v5. The package name is the same, so any references todbplugincan remain as long as those symbols exist within the new package (such as theServefunction). - An easy way to see what functions need to be implemented is to put the following as a
global variable within your package:
var _ dbplugin.Database = (*MyDatabase)(nil). This will fail to compile if theMyDatabasetype does not adhere to thedbplugin.Databaseinterface. - Replace
InitandInitializewith the newInitializefunction definition. The fields thatInitwas taking (configandverifyConnection) are now wrapped intoInitializeRequest. The returnedmap[string]interface{}object is now wrapped intoInitializeResponse. OnlyInitializeis needed to adhere to theDatabaseinterface. - Update
CreateUsertoNewUser. TheNewUserRequestobject contains the username and password of the user to be created. It also includes a list of statements for creating the user as well as several other fields that may or may not be applicable. Your custom plugin should use the password provided in the request, not generate one. If you generate a password instead, Vault will not know about it and will give the caller the wrong password. SetCredentials,RotateRootCredentials, andRenewUserare combined intoUpdateUser. The request object,UpdateUserRequestcontains three parts: the username to change, aChangePasswordand aChangeExpirationobject. When one of the objects is not nil, this indicates that particular field (password or expiration) needs to change. For instance, if theChangePasswordfield is not-nil, the user's password should be changed. This is equivalent to callingSetCredentials. If theChangeExpirationfield is not-nil, the user's expiration date should be changed. This is equivalent to callingRenewUser. Many databases don't need to do anything with the updated expiration.- Update
RevokeUsertoDeleteUser. This is the simplest change. The username to be deleted is enclosed in theDeleteUserRequestobject.