Cleanup path files

This commit is contained in:
Brian Kassouf 2017-04-12 17:35:02 -07:00
parent a9a05f5bba
commit 0cfe1ea81c
5 changed files with 46 additions and 45 deletions

View file

@ -12,7 +12,7 @@ import (
"github.com/hashicorp/vault/logical/framework"
)
const databaseConfigPath = "database/dbs/"
const databaseConfigPath = "database/config/"
// DatabaseConfig is used by the Factory function to configure a DatabaseType
// object.
@ -32,12 +32,6 @@ func Backend(conf *logical.BackendConfig) *databaseBackend {
b.Backend = &framework.Backend{
Help: strings.TrimSpace(backendHelp),
PathsSpecial: &logical.Paths{
Root: []string{
"dbs/plugin/*",
},
},
Paths: []*framework.Path{
pathConfigurePluginConnection(&b),
pathListRoles(&b),
@ -90,7 +84,7 @@ func (b *databaseBackend) getOrCreateDBObj(s logical.Storage, name string) (dbpl
return db, nil
}
entry, err := s.Get(fmt.Sprintf("dbs/%s", name))
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)
}

View file

@ -1,7 +1,6 @@
package dbplugin
import (
"errors"
"fmt"
"net/rpc"
"time"
@ -11,10 +10,6 @@ import (
log "github.com/mgutz/logxi/v1"
)
var (
ErrEmptyPluginName = errors.New("empty plugin name")
)
// DatabaseType is the interface that all database objects must implement.
type DatabaseType interface {
Type() (string, error)
@ -37,10 +32,6 @@ type Statements struct {
// PluginFactory is used to build plugin database types. It wraps the database
// object in a logging and metrics middleware.
func PluginFactory(pluginName string, sys pluginutil.LookWrapper, logger log.Logger) (DatabaseType, error) {
if pluginName == "" {
return nil, ErrEmptyPluginName
}
// Look for plugin in the plugin catalog
pluginMeta, err := sys.LookupPlugin(pluginName)
if err != nil {

View file

@ -1,6 +1,7 @@
package database
import (
"errors"
"fmt"
"github.com/fatih/structs"
@ -9,6 +10,11 @@ import (
"github.com/hashicorp/vault/logical/framework"
)
var (
respErrEmptyPluginName = logical.ErrorResponse("empty plugin name")
respErrEmptyName = logical.ErrorResponse("Empty name attribute given")
)
// pathResetConnection configures a path to reset a plugin.
func pathResetConnection(b *databaseBackend) *framework.Path {
return &framework.Path{
@ -16,7 +22,7 @@ func pathResetConnection(b *databaseBackend) *framework.Path {
Fields: map[string]*framework.FieldSchema{
"name": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Name of this DB type",
Description: "Name of this database connection",
},
},
@ -35,15 +41,17 @@ func (b *databaseBackend) pathConnectionReset() framework.OperationFunc {
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
name := data.Get("name").(string)
if name == "" {
return logical.ErrorResponse("Empty name attribute given"), nil
return respErrEmptyName, nil
}
// Grab the mutex lock
b.Lock()
defer b.Unlock()
// Close plugin and delete the entry in the connections cache.
b.clearConnection(name)
// Execute plugin again, we don't need the object so throw away.
_, err := b.getOrCreateDBObj(req.Storage, name)
if err != nil {
return nil, err
@ -61,14 +69,7 @@ func pathConfigurePluginConnection(b *databaseBackend) *framework.Path {
Fields: map[string]*framework.FieldSchema{
"name": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Name of this DB type",
},
"verify_connection": &framework.FieldSchema{
Type: framework.TypeBool,
Default: true,
Description: `If set, the connection details are verified by
actually connecting to the database`,
Description: "Name of this database connection",
},
"plugin_name": &framework.FieldSchema{
@ -77,6 +78,13 @@ func pathConfigurePluginConnection(b *databaseBackend) *framework.Path {
plugin known to vault. This endpoint will create an instance of
that plugin type.`,
},
"verify_connection": &framework.FieldSchema{
Type: framework.TypeBool,
Default: true,
Description: `If true, the connection details are verified by
actually connecting to the database. Defaults to true.`,
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
@ -94,10 +102,13 @@ func pathConfigurePluginConnection(b *databaseBackend) *framework.Path {
func (b *databaseBackend) connectionReadHandler() framework.OperationFunc {
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
name := data.Get("name").(string)
if name == "" {
return respErrEmptyName, nil
}
entry, err := req.Storage.Get(fmt.Sprintf("dbs/%s", name))
entry, err := req.Storage.Get(fmt.Sprintf("config/%s", name))
if err != nil {
return nil, fmt.Errorf("failed to read connection configuration")
return nil, errors.New("failed to read connection configuration")
}
if entry == nil {
return nil, nil
@ -118,12 +129,12 @@ func (b *databaseBackend) connectionDeleteHandler() framework.OperationFunc {
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
name := data.Get("name").(string)
if name == "" {
return logical.ErrorResponse("Empty name attribute given"), nil
return respErrEmptyName, nil
}
err := req.Storage.Delete(fmt.Sprintf("dbs/%s", name))
err := req.Storage.Delete(fmt.Sprintf("config/%s", name))
if err != nil {
return nil, fmt.Errorf("failed to delete connection configuration")
return nil, errors.New("failed to delete connection configuration")
}
b.Lock()
@ -134,9 +145,9 @@ func (b *databaseBackend) connectionDeleteHandler() framework.OperationFunc {
if err != nil {
return nil, err
}
}
delete(b.connections, name)
delete(b.connections, name)
}
return nil, nil
}
@ -146,22 +157,22 @@ func (b *databaseBackend) connectionDeleteHandler() framework.OperationFunc {
// both builtin and plugin database types.
func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
config := &DatabaseConfig{
ConnectionDetails: data.Raw,
PluginName: data.Get("plugin_name").(string),
pluginName := data.Get("plugin_name").(string)
if pluginName == "" {
return respErrEmptyPluginName, nil
}
name := data.Get("name").(string)
if name == "" {
return logical.ErrorResponse("Empty name attribute given"), nil
return respErrEmptyName, nil
}
verifyConnection := data.Get("verify_connection").(bool)
// Grab the mutex lock
b.Lock()
defer b.Unlock()
config := &DatabaseConfig{
ConnectionDetails: data.Raw,
PluginName: pluginName,
}
db, err := dbplugin.PluginFactory(config.PluginName, b.System(), b.logger)
if err != nil {
@ -174,6 +185,10 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
return logical.ErrorResponse(fmt.Sprintf("Error creating database object: %s", err)), nil
}
// Grab the mutex lock
b.Lock()
defer b.Unlock()
if _, ok := b.connections[name]; ok {
// Close and remove the old connection
err := b.connections[name].Close()
@ -189,7 +204,7 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
b.connections[name] = db
// Store it
entry, err := logical.StorageEntryJSON(fmt.Sprintf("dbs/%s", name), config)
entry, err := logical.StorageEntryJSON(fmt.Sprintf("config/%s", name), config)
if err != nil {
return nil, err
}
@ -198,7 +213,7 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
}
resp := &logical.Response{}
resp.AddWarning("Read access to this endpoint should be controlled via ACLs as it will return the connection string or URL as it is, including passwords, if any.")
resp.AddWarning("Read access to this endpoint should be controlled via ACLs as it will return the connection details as is, including passwords, if any.")
return resp, nil
}
@ -221,7 +236,7 @@ accepts:
plugin known to vault. This endpoint will create an instance of that
plugin type.
* "verify_connection" - A boolean value denoting if the plugin should verify
* "verify_connection" (default: true) - A boolean value denoting if the plugin should verify
it is able to connect to the database using the provided connection
details.
`

View file

@ -109,6 +109,7 @@ func (b *databaseBackend) pathRoleRead() framework.OperationFunc {
return &logical.Response{
Data: map[string]interface{}{
"db_name": role.DBName,
"creation_statements": role.Statements.CreationStatements,
"revocation_statements": role.Statements.RevocationStatements,
"rollback_statements": role.Statements.RollbackStatements,