Cleanup path files
This commit is contained in:
parent
a9a05f5bba
commit
0cfe1ea81c
|
@ -12,7 +12,7 @@ import (
|
||||||
"github.com/hashicorp/vault/logical/framework"
|
"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
|
// DatabaseConfig is used by the Factory function to configure a DatabaseType
|
||||||
// object.
|
// object.
|
||||||
|
@ -32,12 +32,6 @@ func Backend(conf *logical.BackendConfig) *databaseBackend {
|
||||||
b.Backend = &framework.Backend{
|
b.Backend = &framework.Backend{
|
||||||
Help: strings.TrimSpace(backendHelp),
|
Help: strings.TrimSpace(backendHelp),
|
||||||
|
|
||||||
PathsSpecial: &logical.Paths{
|
|
||||||
Root: []string{
|
|
||||||
"dbs/plugin/*",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
Paths: []*framework.Path{
|
Paths: []*framework.Path{
|
||||||
pathConfigurePluginConnection(&b),
|
pathConfigurePluginConnection(&b),
|
||||||
pathListRoles(&b),
|
pathListRoles(&b),
|
||||||
|
@ -90,7 +84,7 @@ func (b *databaseBackend) getOrCreateDBObj(s logical.Storage, name string) (dbpl
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
entry, err := s.Get(fmt.Sprintf("dbs/%s", name))
|
entry, err := s.Get(fmt.Sprintf("config/%s", name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read connection configuration with name: %s", name)
|
return nil, fmt.Errorf("failed to read connection configuration with name: %s", name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package dbplugin
|
package dbplugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/rpc"
|
"net/rpc"
|
||||||
"time"
|
"time"
|
||||||
|
@ -11,10 +10,6 @@ import (
|
||||||
log "github.com/mgutz/logxi/v1"
|
log "github.com/mgutz/logxi/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
ErrEmptyPluginName = errors.New("empty plugin name")
|
|
||||||
)
|
|
||||||
|
|
||||||
// DatabaseType is the interface that all database objects must implement.
|
// DatabaseType is the interface that all database objects must implement.
|
||||||
type DatabaseType interface {
|
type DatabaseType interface {
|
||||||
Type() (string, error)
|
Type() (string, error)
|
||||||
|
@ -37,10 +32,6 @@ type Statements struct {
|
||||||
// PluginFactory is used to build plugin database types. It wraps the database
|
// PluginFactory is used to build plugin database types. It wraps the database
|
||||||
// object in a logging and metrics middleware.
|
// object in a logging and metrics middleware.
|
||||||
func PluginFactory(pluginName string, sys pluginutil.LookWrapper, logger log.Logger) (DatabaseType, error) {
|
func PluginFactory(pluginName string, sys pluginutil.LookWrapper, logger log.Logger) (DatabaseType, error) {
|
||||||
if pluginName == "" {
|
|
||||||
return nil, ErrEmptyPluginName
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look for plugin in the plugin catalog
|
// Look for plugin in the plugin catalog
|
||||||
pluginMeta, err := sys.LookupPlugin(pluginName)
|
pluginMeta, err := sys.LookupPlugin(pluginName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/fatih/structs"
|
"github.com/fatih/structs"
|
||||||
|
@ -9,6 +10,11 @@ import (
|
||||||
"github.com/hashicorp/vault/logical/framework"
|
"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.
|
// pathResetConnection configures a path to reset a plugin.
|
||||||
func pathResetConnection(b *databaseBackend) *framework.Path {
|
func pathResetConnection(b *databaseBackend) *framework.Path {
|
||||||
return &framework.Path{
|
return &framework.Path{
|
||||||
|
@ -16,7 +22,7 @@ func pathResetConnection(b *databaseBackend) *framework.Path {
|
||||||
Fields: map[string]*framework.FieldSchema{
|
Fields: map[string]*framework.FieldSchema{
|
||||||
"name": &framework.FieldSchema{
|
"name": &framework.FieldSchema{
|
||||||
Type: framework.TypeString,
|
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) {
|
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||||
name := data.Get("name").(string)
|
name := data.Get("name").(string)
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return logical.ErrorResponse("Empty name attribute given"), nil
|
return respErrEmptyName, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab the mutex lock
|
// Grab the mutex lock
|
||||||
b.Lock()
|
b.Lock()
|
||||||
defer b.Unlock()
|
defer b.Unlock()
|
||||||
|
|
||||||
|
// Close plugin and delete the entry in the connections cache.
|
||||||
b.clearConnection(name)
|
b.clearConnection(name)
|
||||||
|
|
||||||
|
// Execute plugin again, we don't need the object so throw away.
|
||||||
_, err := b.getOrCreateDBObj(req.Storage, name)
|
_, err := b.getOrCreateDBObj(req.Storage, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -61,14 +69,7 @@ func pathConfigurePluginConnection(b *databaseBackend) *framework.Path {
|
||||||
Fields: map[string]*framework.FieldSchema{
|
Fields: map[string]*framework.FieldSchema{
|
||||||
"name": &framework.FieldSchema{
|
"name": &framework.FieldSchema{
|
||||||
Type: framework.TypeString,
|
Type: framework.TypeString,
|
||||||
Description: "Name of this DB type",
|
Description: "Name of this database connection",
|
||||||
},
|
|
||||||
|
|
||||||
"verify_connection": &framework.FieldSchema{
|
|
||||||
Type: framework.TypeBool,
|
|
||||||
Default: true,
|
|
||||||
Description: `If set, the connection details are verified by
|
|
||||||
actually connecting to the database`,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"plugin_name": &framework.FieldSchema{
|
"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
|
plugin known to vault. This endpoint will create an instance of
|
||||||
that plugin type.`,
|
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{
|
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||||
|
@ -94,10 +102,13 @@ func pathConfigurePluginConnection(b *databaseBackend) *framework.Path {
|
||||||
func (b *databaseBackend) connectionReadHandler() framework.OperationFunc {
|
func (b *databaseBackend) connectionReadHandler() framework.OperationFunc {
|
||||||
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||||
name := data.Get("name").(string)
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read connection configuration")
|
return nil, errors.New("failed to read connection configuration")
|
||||||
}
|
}
|
||||||
if entry == nil {
|
if entry == nil {
|
||||||
return nil, 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) {
|
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||||
name := data.Get("name").(string)
|
name := data.Get("name").(string)
|
||||||
if name == "" {
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to delete connection configuration")
|
return nil, errors.New("failed to delete connection configuration")
|
||||||
}
|
}
|
||||||
|
|
||||||
b.Lock()
|
b.Lock()
|
||||||
|
@ -134,9 +145,9 @@ func (b *databaseBackend) connectionDeleteHandler() framework.OperationFunc {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
delete(b.connections, name)
|
delete(b.connections, name)
|
||||||
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -146,22 +157,22 @@ func (b *databaseBackend) connectionDeleteHandler() framework.OperationFunc {
|
||||||
// both builtin and plugin database types.
|
// both builtin and plugin database types.
|
||||||
func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
|
func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
|
||||||
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||||
|
pluginName := data.Get("plugin_name").(string)
|
||||||
config := &DatabaseConfig{
|
if pluginName == "" {
|
||||||
ConnectionDetails: data.Raw,
|
return respErrEmptyPluginName, nil
|
||||||
PluginName: data.Get("plugin_name").(string),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
name := data.Get("name").(string)
|
name := data.Get("name").(string)
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return logical.ErrorResponse("Empty name attribute given"), nil
|
return respErrEmptyName, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyConnection := data.Get("verify_connection").(bool)
|
verifyConnection := data.Get("verify_connection").(bool)
|
||||||
|
|
||||||
// Grab the mutex lock
|
config := &DatabaseConfig{
|
||||||
b.Lock()
|
ConnectionDetails: data.Raw,
|
||||||
defer b.Unlock()
|
PluginName: pluginName,
|
||||||
|
}
|
||||||
|
|
||||||
db, err := dbplugin.PluginFactory(config.PluginName, b.System(), b.logger)
|
db, err := dbplugin.PluginFactory(config.PluginName, b.System(), b.logger)
|
||||||
if err != nil {
|
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
|
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 {
|
if _, ok := b.connections[name]; ok {
|
||||||
// Close and remove the old connection
|
// Close and remove the old connection
|
||||||
err := b.connections[name].Close()
|
err := b.connections[name].Close()
|
||||||
|
@ -189,7 +204,7 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
|
||||||
b.connections[name] = db
|
b.connections[name] = db
|
||||||
|
|
||||||
// Store it
|
// 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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -198,7 +213,7 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := &logical.Response{}
|
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
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
@ -221,7 +236,7 @@ accepts:
|
||||||
plugin known to vault. This endpoint will create an instance of that
|
plugin known to vault. This endpoint will create an instance of that
|
||||||
plugin type.
|
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
|
it is able to connect to the database using the provided connection
|
||||||
details.
|
details.
|
||||||
`
|
`
|
||||||
|
|
|
@ -109,6 +109,7 @@ func (b *databaseBackend) pathRoleRead() framework.OperationFunc {
|
||||||
|
|
||||||
return &logical.Response{
|
return &logical.Response{
|
||||||
Data: map[string]interface{}{
|
Data: map[string]interface{}{
|
||||||
|
"db_name": role.DBName,
|
||||||
"creation_statements": role.Statements.CreationStatements,
|
"creation_statements": role.Statements.CreationStatements,
|
||||||
"revocation_statements": role.Statements.RevocationStatements,
|
"revocation_statements": role.Statements.RevocationStatements,
|
||||||
"rollback_statements": role.Statements.RollbackStatements,
|
"rollback_statements": role.Statements.RollbackStatements,
|
||||||
|
|
Loading…
Reference in a new issue