Update the builtin keys; move catalog to core; protect against unset plugin directory

This commit is contained in:
Brian Kassouf
2017-04-24 10:30:33 -07:00
parent 3ceb7b69e1
commit f4ef3df4bd
7 changed files with 47 additions and 62 deletions

View File

@@ -8,7 +8,6 @@ import (
"net/url"
"os"
"os/signal"
"path/filepath"
"runtime"
"sort"
"strconv"
@@ -21,7 +20,6 @@ import (
colorable "github.com/mattn/go-colorable"
log "github.com/mgutz/logxi/v1"
homedir "github.com/mitchellh/go-homedir"
"google.golang.org/grpc/grpclog"
@@ -245,23 +243,6 @@ func (c *ServerCommand) Run(args []string) int {
coreConfig.DevToken = devRootTokenID
}
if config.PluginDirectory == "" {
homePath, err := homedir.Dir()
if err != nil {
c.Ui.Output(fmt.Sprintf(
"Error getting user's home directory: %v", err))
return 1
}
coreConfig.PluginDirectory = filepath.Join(homePath, "/.vault-plugins/")
err = os.Mkdir(coreConfig.PluginDirectory, 0700)
if err != nil && !os.IsExist(err) {
c.Ui.Output(fmt.Sprintf(
"Error making default plugin directory: %v", err))
return 1
}
}
var disableClustering bool
// Initialize the separate HA storage backend, if it exists

View File

@@ -7,29 +7,21 @@ import (
type BuiltinFactory func() (interface{}, error)
var BuiltinPlugins *builtinPlugins = &builtinPlugins{
plugins: map[string]BuiltinFactory{
var plugins map[string]BuiltinFactory = map[string]BuiltinFactory{
"mysql-database-plugin": mysql.New,
"postgresql-database-plugin": postgresql.New,
},
}
// The list of builtin plugins should not be changed by any other package, so we
// store them in an unexported variable in this unexported struct.
type builtinPlugins struct {
plugins map[string]BuiltinFactory
}
func (b *builtinPlugins) Get(name string) (BuiltinFactory, bool) {
f, ok := b.plugins[name]
func Get(name string) (BuiltinFactory, bool) {
f, ok := plugins[name]
return f, ok
}
func (b *builtinPlugins) Keys() []string {
keys := make([]string, len(b.plugins))
func Keys() []string {
keys := make([]string, len(plugins))
i := 0
for k := range b.plugins {
for k := range plugins {
keys[i] = k
i++
}

View File

@@ -12,8 +12,8 @@ import (
)
var (
// PluginUnwrapTokenEnv is the ENV name used to pass unwrap tokens to the
// plugin.
// PluginUnwrapTokenEnv is the ENV name used to pass the configuration for
// enabling mlock
PluginMlockEnabled = "VAULT_PLUGIN_MLOCK_ENABLED"
)

View File

@@ -711,12 +711,18 @@ func NewSystemBackend(core *Core, config *logical.BackendConfig) (logical.Backen
Fields: map[string]*framework.FieldSchema{
"name": &framework.FieldSchema{
Type: framework.TypeString,
Description: "The name of the plugin",
},
"sha_256": &framework.FieldSchema{
Type: framework.TypeString,
Description: `The SHA256 sum of the executable used in the
command field. This should be HEX encoded.`,
},
"command": &framework.FieldSchema{
Type: framework.TypeString,
Description: `The command used to start the plugin. The
executable defined in this command must exist in vault's
plugin directory.`,
},
},
@@ -767,8 +773,7 @@ func (b *SystemBackend) handlePluginCatalogList(req *logical.Request, d *framewo
return nil, err
}
resp := logical.ListResponse(plugins)
return resp, nil
return logical.ListResponse(plugins), nil
}
func (b *SystemBackend) handlePluginCatalogUpdate(req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
@@ -2524,7 +2529,7 @@ This path responds to the following HTTP methods.
`Configures the plugins known to vault`,
`
This path responds to the following HTTP methods.
GET /
LIST /
Returns a list of names of configured plugins.
GET /<name>

View File

@@ -1129,8 +1129,8 @@ func TestSystemBackend_PluginCatalog_CRUD(t *testing.T) {
t.Fatalf("err: %v", err)
}
if len(resp.Data["keys"].([]string)) != len(builtinplugins.BuiltinPlugins.Keys()) {
t.Fatalf("Wrong number of plugins, got %d, expected %d", len(resp.Data["keys"].([]string)), len(builtinplugins.BuiltinPlugins.Keys()))
if len(resp.Data["keys"].([]string)) != len(builtinplugins.Keys()) {
t.Fatalf("Wrong number of plugins, got %d, expected %d", len(resp.Data["keys"].([]string)), len(builtinplugins.Keys()))
}
req = logical.TestRequest(t, logical.ReadOperation, "plugin-catalog/mysql-database-plugin")
@@ -1143,7 +1143,7 @@ func TestSystemBackend_PluginCatalog_CRUD(t *testing.T) {
Name: "mysql-database-plugin",
Builtin: true,
}
expectedBuiltin.BuiltinFactory, _ = builtinplugins.BuiltinPlugins.Get("mysql-database-plugin")
expectedBuiltin.BuiltinFactory, _ = builtinplugins.Get("mysql-database-plugin")
p := resp.Data["plugin"].(*pluginutil.PluginRunner)
if &(p.BuiltinFactory) == &(expectedBuiltin.BuiltinFactory) {

View File

@@ -16,7 +16,8 @@ import (
)
var (
pluginCatalogPrefix = "plugin-catalog/"
pluginCatalogPath = "core/plugin-catalog/"
ErrDirectoryNotConfigured = errors.New("could not set plugin, plugin directory is not configured")
)
// PluginCatalog keeps a record of plugins known to vault. External plugins need
@@ -31,7 +32,7 @@ type PluginCatalog struct {
func (c *Core) setupPluginCatalog() error {
c.pluginCatalog = &PluginCatalog{
catalogView: c.systemBarrierView.SubView(pluginCatalogPrefix),
catalogView: NewBarrierView(c.barrier, pluginCatalogPath),
directory: c.pluginDirectory,
}
@@ -45,6 +46,8 @@ func (c *PluginCatalog) Get(name string) (*pluginutil.PluginRunner, error) {
c.lock.RLock()
defer c.lock.RUnlock()
// If the directory isn't set only look for builtin plugins.
if c.directory != "" {
// Look for external plugins in the barrier
out, err := c.catalogView.Get(name)
if err != nil {
@@ -58,9 +61,9 @@ func (c *PluginCatalog) Get(name string) (*pluginutil.PluginRunner, error) {
return entry, nil
}
}
// Look for builtin plugins
if factory, ok := builtinplugins.BuiltinPlugins.Get(name); ok {
if factory, ok := builtinplugins.Get(name); ok {
return &pluginutil.PluginRunner{
Name: name,
Builtin: true,
@@ -74,6 +77,10 @@ func (c *PluginCatalog) Get(name string) (*pluginutil.PluginRunner, error) {
// Set registers a new external plugin with the catalog, or updates an existing
// external plugin. It takes the name, command and SHA256 of the plugin.
func (c *PluginCatalog) Set(name, command string, sha256 []byte) error {
if c.directory == "" {
return ErrDirectoryNotConfigured
}
c.lock.Lock()
defer c.lock.Unlock()
@@ -143,7 +150,7 @@ func (c *PluginCatalog) List() ([]string, error) {
}
// Get the keys for builtin plugins
builtinKeys := builtinplugins.BuiltinPlugins.Keys()
builtinKeys := builtinplugins.Keys()
// Use a map to unique the two lists
mapKeys := make(map[string]bool)

View File

@@ -32,7 +32,7 @@ func TestPluginCatalog_CRUD(t *testing.T) {
Name: "mysql-database-plugin",
Builtin: true,
}
expectedBuiltin.BuiltinFactory, _ = builtinplugins.BuiltinPlugins.Get("mysql-database-plugin")
expectedBuiltin.BuiltinFactory, _ = builtinplugins.Get("mysql-database-plugin")
if &(p.BuiltinFactory) == &(expectedBuiltin.BuiltinFactory) {
t.Fatal("expected BuiltinFactory did not match actual")
@@ -90,7 +90,7 @@ func TestPluginCatalog_CRUD(t *testing.T) {
Name: "mysql-database-plugin",
Builtin: true,
}
expectedBuiltin.BuiltinFactory, _ = builtinplugins.BuiltinPlugins.Get("mysql-database-plugin")
expectedBuiltin.BuiltinFactory, _ = builtinplugins.Get("mysql-database-plugin")
if &(p.BuiltinFactory) == &(expectedBuiltin.BuiltinFactory) {
t.Fatal("expected BuiltinFactory did not match actual")
@@ -113,7 +113,7 @@ func TestPluginCatalog_List(t *testing.T) {
core.pluginCatalog.directory = sym
// Get builtin plugins and sort them
builtinKeys := builtinplugins.BuiltinPlugins.Keys()
builtinKeys := builtinplugins.Keys()
sort.Strings(builtinKeys)
// List only builtin plugins