mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 11:08:10 +00:00
Database Root Credential Rotation (#3976)
* redoing connection handling * a little more cleanup * empty implementation of rotation * updating rotate signature * signature update * updating interfaces again :( * changing back to interface * adding templated url support and rotation for postgres * adding correct username * return updates * updating statements to be a list * adding error sanitizing middleware * fixing log sanitizier * adding postgres rotate test * removing conf from rotate * adding rotate command * adding mysql rotate * finishing up the endpoint in the db backend for rotate * no more structs, just store raw config * fixing tests * adding db instance lock * adding support for statement list in cassandra * wip redoing interface to support BC * adding falllback for Initialize implementation * adding backwards compat for statements * fix tests * fix more tests * fixing up tests, switching to new fields in statements * fixing more tests * adding mssql and mysql * wrapping all the things in middleware, implementing templating for mongodb * wrapping all db servers with error santizer * fixing test * store the name with the db instance * adding rotate to cassandra * adding compatibility translation to both server and plugin * reordering a few things * store the name with the db instance * reordering * adding a few more tests * switch secret values from slice to map * addressing some feedback * reinstate execute plugin after resetting connection * set database connection to closed * switching secret values func to map[string]interface for potential future uses * addressing feedback
This commit is contained in:
@@ -14,7 +14,9 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/vault/plugins/helper/database/connutil"
|
||||
"github.com/hashicorp/vault/plugins/helper/database/dbutil"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
|
||||
"gopkg.in/mgo.v2"
|
||||
@@ -25,28 +27,43 @@ import (
|
||||
type mongoDBConnectionProducer struct {
|
||||
ConnectionURL string `json:"connection_url" structs:"connection_url" mapstructure:"connection_url"`
|
||||
WriteConcern string `json:"write_concern" structs:"write_concern" mapstructure:"write_concern"`
|
||||
Username string `json:"username" structs:"username" mapstructure:"username"`
|
||||
Password string `json:"password" structs:"password" mapstructure:"password"`
|
||||
|
||||
Initialized bool
|
||||
RawConfig map[string]interface{}
|
||||
Type string
|
||||
session *mgo.Session
|
||||
safe *mgo.Safe
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
// Initialize parses connection configuration.
|
||||
func (c *mongoDBConnectionProducer) Initialize(ctx context.Context, conf map[string]interface{}, verifyConnection bool) error {
|
||||
_, err := c.Init(ctx, conf, verifyConnection)
|
||||
return err
|
||||
}
|
||||
|
||||
// Initialize parses connection configuration.
|
||||
func (c *mongoDBConnectionProducer) Init(ctx context.Context, conf map[string]interface{}, verifyConnection bool) (map[string]interface{}, error) {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
c.RawConfig = conf
|
||||
|
||||
err := mapstructure.WeakDecode(conf, c)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(c.ConnectionURL) == 0 {
|
||||
return fmt.Errorf("connection_url cannot be empty")
|
||||
return nil, fmt.Errorf("connection_url cannot be empty")
|
||||
}
|
||||
|
||||
c.ConnectionURL = dbutil.QueryHelper(c.ConnectionURL, map[string]string{
|
||||
"username": c.Username,
|
||||
"password": c.Password,
|
||||
})
|
||||
|
||||
if c.WriteConcern != "" {
|
||||
input := c.WriteConcern
|
||||
|
||||
@@ -60,13 +77,13 @@ func (c *mongoDBConnectionProducer) Initialize(ctx context.Context, conf map[str
|
||||
concern := &mgo.Safe{}
|
||||
err = json.Unmarshal([]byte(input), concern)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error mashalling write_concern: %s", err)
|
||||
return nil, errwrap.Wrapf("error mashalling write_concern: {{err}}", err)
|
||||
}
|
||||
|
||||
// Guard against empty, non-nil mgo.Safe object; we don't want to pass that
|
||||
// into mgo.SetSafe in Connection().
|
||||
if (mgo.Safe{} == *concern) {
|
||||
return fmt.Errorf("provided write_concern values did not map to any mgo.Safe fields")
|
||||
return nil, fmt.Errorf("provided write_concern values did not map to any mgo.Safe fields")
|
||||
}
|
||||
c.safe = concern
|
||||
}
|
||||
@@ -77,15 +94,15 @@ func (c *mongoDBConnectionProducer) Initialize(ctx context.Context, conf map[str
|
||||
|
||||
if verifyConnection {
|
||||
if _, err := c.Connection(ctx); err != nil {
|
||||
return fmt.Errorf("error verifying connection: %s", err)
|
||||
return nil, errwrap.Wrapf("error verifying connection: {{err}}", err)
|
||||
}
|
||||
|
||||
if err := c.session.Ping(); err != nil {
|
||||
return fmt.Errorf("error verifying connection: %s", err)
|
||||
return nil, errwrap.Wrapf("error verifying connection: {{err}}", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return conf, nil
|
||||
}
|
||||
|
||||
// Connection creates or returns an existing a database connection. If the session fails
|
||||
@@ -203,3 +220,9 @@ func parseMongoURL(rawURL string) (*mgo.DialInfo, error) {
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
func (c *mongoDBConnectionProducer) secretValues() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
c.Password: "[password]",
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user