-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Combined Database Backend with Plugins #2200
Merged
Merged
Changes from 153 commits
Commits
Show all changes
162 commits
Select commit
Hold shift + click to select a range
3d77a9a
Begin work on database refactor
ad17d11
More work on refactor and cassandra database
bfbb104
Add mysql database type
cee3dc9
s/Statement/Statements/
5e2cffc
Add max connection lifetime param and set consistancy on cassandra se…
e442917
Add mysql into the factory
fa8da4c
Fix mysql connections
4d33509
Make db instances immutable and add a reset path to tear down and cre…
354233f
rename mysql variable
briankassouf c823ad0
Update locking functionaility
briankassouf 1d23bbb
Remove double lock
briankassouf 01300e0
Remove unused sql object
briankassouf 78fdc2a
Pass statements object
briankassouf 73200db
Add defaults to the cassandra databse type
briankassouf cd68899
Fix renew and revoke calls
briankassouf 00359cd
Update secrets fields
briankassouf d4ea6c1
Add plugin features
3766ab1
Add plugin file
b63147b
Add special path to enforce root on plugin configuration
briankassouf 72a878b
Rename reset to close
briankassouf a0d207e
Add checksum attribute
briankassouf c111b02
Add a way to initalize plugins and builtin databases the same way.
briankassouf 143166b
Add a metrics middleware
briankassouf a6ae4bd
wrap plugin database type with metrics middleware
briankassouf 5b05f62
Work on TLS communication over plugins
briankassouf 3890f19
Break tls code into helper library
briankassouf 2ef1cbf
Comment and slight refactor of the TLS plugin helper
briankassouf a878791
Update the name of PluginUnwrapTokenEnv
briankassouf 4043f53
Add a secure config to verify the checksum of the plugin
briankassouf 404596e
Change the handshake config from the default
briankassouf ff6749b
Comment and fix plugin Type function
briankassouf 2fdb342
Verify connections regardless of if this connections is already existing
briankassouf 2d6f36d
Add a delete method
briankassouf 1be8136
Fix race with deleting the connection
9aaec25
Add a error message for empty creation statement
73e553a
Add test files for postgres and mysql databases
cab491f
s/postgres/mysql/
a1b7246
Remove unsused code block
e870e39
More work on getting tests to pass
ca026c6
Remove the unused sync.Once object
b2c4555
Wrap the database calls with tracing information
d93378b
Fix for checking types of database on update
6de5cfa
Add functionaility to build db objects from disk so restarts work
0c562fa
Update tests
947fd66
Cleanup the db factory code and add comments
8ef78f0
Add comments to connection and credential producers
1d3d3b7
fix for plugin commands that have more than one paramater
2b08521
Database refactor mssql (#2562)
calvn ac519ab
Plugin catalog
briankassouf b54e1cd
Merge branch 'database-refactor' of github.com:hashicorp/vault into d…
briankassouf 1faa5fc
On change of configuration rotate the database type
briankassouf 8e3cb50
Database refactor invalidate (#2566)
calvn df944f2
Don't return strings, always structs
73a2cdf
Do not mark conn as initialized until the end (#2567)
calvn f6b45bd
Execute builtin plugins
485b331
Add a cli command to run builtin plugins
8f88452
move builtin plugins list to the pluginutil
8a2e29c
Refactor to use builtin plugins from an external repo
0da69cf
Add postgres builtin plugin
8e77bd9
Move plugin code into sub directory
9ae5a2a
Add backend test
3c1c388
Update backend tests
73f66f8
Update the interface for plugins removing functions for creating creds
64efc50
Update plugin test
f54c4de
Add a flag to tell plugins to verify the connection was successful
de36d61
Mlock the plugin process
da4d9a8
Remove unnecessary abstraction
8f75c30
Update help text and comments
8c264c6
Add remaining crud functions to plugin catalog and tests
0e08279
Add path help and comments for plugin-catalog
cb844b5
Add test for logical_system plugin-catalog handling
1bc0243
Fix RootPaths test
c9dc7b8
vendor go-plugin
f2401c0
Merge branch 'master' into database-refactor
03e2bcb
Update Type() to return an error
4c75326
Cleanup path files
33d66f3
Add comments to the plugin runner
b20c177
Add allowed_roles parameter and checks
07f3f4f
Update the plugin directory logic
be50cba
Move plugins into main vault repo
ea41734
Move mssql to be an acceptance test
1f6bf29
Only run mssql acceptance test when running as VAULT_ACC=1
370dd2d
Adding explicit database to sp_msloginmappings call (#2611)
chrishoffman 8b7fa73
Fix cassandra deps breakage
afc5be1
Merge remote-tracking branch 'oss/master' into database-refactor
d9ce189
Use the same TLS cert for the server and client
62cae4a
Merge branch 'master-oss' into database-refactor
jefferai f1fa617
Calls to builtin plugins now go directly to the implementation instea…
a3f6580
Merge remote-tracking branch 'oss/database-refactor' into database-re…
9abc31e
Fix tests
3ceb7b6
Fix tests
c5d5abe
Add cassandra plugin
calvn 2faa08d
Remove commented old method signature
calvn f4ef3df
Update the builtin keys; move catalog to core; protect against unset …
707e6ca
Update path for the plugin catalog in logical system
4cda9ea
Update the ResponseWrapData function to return a wrapping.ResponseWra…
4c306bd
Change MlockDisabled to MlockEnabled
7e3f5e6
Update root paths test
4315e68
Fix test
f6b96cc
s/DatabaseType/Database/
194695f
Don't uppercase ErrorResponses
1971d65
Only run Abs on the plugin directory if it's set
57f78c4
return a 404 when no plugin is found
630962b
Update test to reflect the correct read response
6741811
Update logging to new structure
22612ad
Use TypeCommaStringSlice for allowed_roles
58b0bbd
Rename path_role_create to path_creds_create
e187576
Update the connection details data and fix allowedRoles
6131bdd
Default deny when allowed roles is empty
37aacba
Change ttl types to TypeDurationSecond
d8dbfc6
Update the error messages for renew and revoke
dc9740d
Add mssql builtin plugin type
cb13786
Fix MSSQL test
6b05047
Update to a RWMutex
f92d686
Add an error check to reset a plugin if it is closed
2e2d382
Add check to ensure we don't overwrite existing connections
230a36c
Update New() func signature and its references
calvn 47df4ac
Merge pull request #2632 from hashicorp/cassandra-plugin
calvn 766b909
If user provides a revocation statement for MSSQL plugin honor it
6684e5c
Update username length for MSSQL
445a0e3
Update the username length for postgresql
f3e7ad7
Honor statements for RevokeUser on Cassandra backend, add method comm…
calvn b87f8a1
Update interface name from Wrapper to a more descriptive RunnerUtil
6ca436c
Don't store an error response as a package variable
66630f6
Add test for custiom mssql revoke statement
d68f283
Prepend a 'v-' to the sql username strings
885398e
Add internals doc for plugins
31541b7
Add plugins interal page to the sidebar:
6ddfe9a
Rename NewPluginServer to just Serve
7f92c5f
Fix documentation
d300c23
Add website skeleton
jefferai 1df8ec9
Update the api for serving plugins and provide a utility to pass TLS …
6d4f1aa
Merge remote-tracking branch 'oss/database-refactor' into database-re…
30a02ed
Don't need to explictly set redirectAddrs
6e7696b
Remove unused TestCoreUnsealedWithListener function
fe86f06
Fix a few PR comments
dc5979e
Fix wording in docs
d230446
Update docs and add cassandra as a builtin plugin
60753dc
Only wrap in tracing middleware if the logger is set to trace level
2be2e4c
Update docs for the database backend and it's plugins
85967cb
Add custom plugins docs page
78b27fa
Add API docs
799cd3c
Upate links in docs
311acb3
Add the plugins catalog API docs
f424a9a
Use log to output errors instead of fmt
c381b00
Use ParseDurationSecond to parse the timeouts in connutil
657826d
Add the other mysql plugin types with the correct username length set…
5b8ce92
Fix mysql plugin tests
3ca266b
Fix parsing the connection duration when it's nil
3fcf1ad
Fix the TLS functionality in cassandra plugin
a3619c4
Update databse backend tests to use the APIClientMeta for the plugin …
2af2b85
Feedback from PR
9e28b03
add new mysql plugin names and fix grammar
c825362
PR comments
55f1f51
Merge remote-tracking branch 'oss/master' into database-refactor
886f873
Update docs and return a better error message
17bea65
Don't store the plugin directory prepended command in the barrier, pr…
fcd4f90
Merge remote-tracking branch 'oss/master' into database-refactor
2e82e00
update docs
65b7bba
Update mssql docs
calvn 3f7ea0d
Merge branch 'database-refactor' of github.com:hashicorp/vault into d…
calvn c48b7fa
Few docs updates
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
package database | ||
|
||
import ( | ||
"fmt" | ||
"net/rpc" | ||
"strings" | ||
"sync" | ||
|
||
log "github.com/mgutz/logxi/v1" | ||
|
||
"github.com/hashicorp/vault/builtin/logical/database/dbplugin" | ||
"github.com/hashicorp/vault/logical" | ||
"github.com/hashicorp/vault/logical/framework" | ||
) | ||
|
||
const databaseConfigPath = "database/config/" | ||
|
||
func Factory(conf *logical.BackendConfig) (logical.Backend, error) { | ||
return Backend(conf).Setup(conf) | ||
} | ||
|
||
func Backend(conf *logical.BackendConfig) *databaseBackend { | ||
var b databaseBackend | ||
b.Backend = &framework.Backend{ | ||
Help: strings.TrimSpace(backendHelp), | ||
|
||
Paths: []*framework.Path{ | ||
pathConfigurePluginConnection(&b), | ||
pathListRoles(&b), | ||
pathRoles(&b), | ||
pathCredsCreate(&b), | ||
pathResetConnection(&b), | ||
}, | ||
|
||
Secrets: []*framework.Secret{ | ||
secretCreds(&b), | ||
}, | ||
|
||
Clean: b.closeAllDBs, | ||
|
||
Invalidate: b.invalidate, | ||
} | ||
|
||
b.logger = conf.Logger | ||
b.connections = make(map[string]dbplugin.Database) | ||
return &b | ||
} | ||
|
||
type databaseBackend struct { | ||
connections map[string]dbplugin.Database | ||
logger log.Logger | ||
|
||
*framework.Backend | ||
sync.RWMutex | ||
} | ||
|
||
// closeAllDBs closes all connections from all database types | ||
func (b *databaseBackend) closeAllDBs() { | ||
b.Lock() | ||
defer b.Unlock() | ||
|
||
for _, db := range b.connections { | ||
db.Close() | ||
} | ||
|
||
b.connections = make(map[string]dbplugin.Database) | ||
} | ||
|
||
// This function is used to retrieve a database object either from the cached | ||
// connection map. The caller of this function needs to hold the backend's read | ||
// lock. | ||
func (b *databaseBackend) getDBObj(name string) (dbplugin.Database, bool) { | ||
db, ok := b.connections[name] | ||
return db, ok | ||
} | ||
|
||
// This function creates a new db object from the stored configuration and | ||
// caches it in the connections map. The caller of this function needs to hold | ||
// the backend's write lock | ||
func (b *databaseBackend) createDBObj(s logical.Storage, name string) (dbplugin.Database, error) { | ||
db, ok := b.connections[name] | ||
if ok { | ||
return db, nil | ||
} | ||
|
||
config, err := b.DatabaseConfig(s, name) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
db, err = dbplugin.PluginFactory(config.PluginName, b.System(), b.logger) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
err = db.Initialize(config.ConnectionDetails, true) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
b.connections[name] = db | ||
|
||
return db, nil | ||
} | ||
|
||
func (b *databaseBackend) DatabaseConfig(s logical.Storage, name string) (*DatabaseConfig, error) { | ||
entry, err := s.Get(fmt.Sprintf("config/%s", name)) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to read connection configuration with name: %s", name) | ||
} | ||
if entry == nil { | ||
return nil, fmt.Errorf("failed to find entry for connection with name: %s", name) | ||
} | ||
|
||
var config DatabaseConfig | ||
if err := entry.DecodeJSON(&config); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &config, nil | ||
} | ||
|
||
func (b *databaseBackend) Role(s logical.Storage, roleName string) (*roleEntry, error) { | ||
entry, err := s.Get("role/" + roleName) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if entry == nil { | ||
return nil, nil | ||
} | ||
|
||
var result roleEntry | ||
if err := entry.DecodeJSON(&result); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &result, nil | ||
} | ||
|
||
func (b *databaseBackend) invalidate(key string) { | ||
b.Lock() | ||
defer b.Unlock() | ||
|
||
switch { | ||
case strings.HasPrefix(key, databaseConfigPath): | ||
name := strings.TrimPrefix(key, databaseConfigPath) | ||
b.clearConnection(name) | ||
} | ||
} | ||
|
||
// clearConnection closes the database connection and | ||
// removes it from the b.connections map. | ||
func (b *databaseBackend) clearConnection(name string) { | ||
db, ok := b.connections[name] | ||
if ok { | ||
db.Close() | ||
delete(b.connections, name) | ||
} | ||
} | ||
|
||
func (b *databaseBackend) closeIfShutdown(name string, err error) { | ||
// Plugin has shutdown, close it so next call can reconnect. | ||
if err == rpc.ErrShutdown { | ||
b.Lock() | ||
b.clearConnection(name) | ||
b.Unlock() | ||
} | ||
} | ||
|
||
const backendHelp = ` | ||
The database backend supports using many different databases | ||
as secret backends, including but not limited to: | ||
cassandra, mssql, mysql, postgres | ||
|
||
After mounting this backend, configure it using the endpoints within | ||
the "database/config/" path. | ||
` |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should
err
be appended and returned back as well?