mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 19:17:58 +00:00
Calls to builtin plugins now go directly to the implementation instead of go-plugin
This commit is contained in:
@@ -11,10 +11,10 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
|
||||
"github.com/hashicorp/vault/helper/builtinplugins"
|
||||
"github.com/hashicorp/vault/helper/pluginutil"
|
||||
"github.com/hashicorp/vault/http"
|
||||
"github.com/hashicorp/vault/logical"
|
||||
"github.com/hashicorp/vault/plugins/database/postgresql"
|
||||
"github.com/hashicorp/vault/vault"
|
||||
"github.com/lib/pq"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
@@ -91,8 +91,7 @@ func TestBackend_PluginMain(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
f, _ := builtinplugins.BuiltinPlugins.Get("postgresql-database-plugin")
|
||||
f()
|
||||
postgresql.Run()
|
||||
}
|
||||
|
||||
func TestBackend_config_connection(t *testing.T) {
|
||||
|
@@ -33,16 +33,33 @@ type Statements struct {
|
||||
// object in a logging and metrics middleware.
|
||||
func PluginFactory(pluginName string, sys pluginutil.LookWrapper, logger log.Logger) (DatabaseType, error) {
|
||||
// Look for plugin in the plugin catalog
|
||||
pluginMeta, err := sys.LookupPlugin(pluginName)
|
||||
pluginRunner, err := sys.LookupPlugin(pluginName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var db DatabaseType
|
||||
if pluginRunner.Builtin {
|
||||
// Plugin is builtin so we can retrieve an instance of the interface
|
||||
// from the pluginRunner. Then cast it to a DatabaseType.
|
||||
dbRaw, err := pluginRunner.BuiltinFactory()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting plugin type: %s", err)
|
||||
}
|
||||
|
||||
var ok bool
|
||||
db, ok = dbRaw.(DatabaseType)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unsuported database type: %s", pluginName)
|
||||
}
|
||||
|
||||
} else {
|
||||
// create a DatabasePluginClient instance
|
||||
db, err := newPluginClient(sys, pluginMeta)
|
||||
db, err = newPluginClient(sys, pluginRunner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
typeStr, err := db.Type()
|
||||
if err != nil {
|
||||
|
@@ -331,11 +331,5 @@ func Commands(metaPtr *meta.Meta) map[string]cli.CommandFactory {
|
||||
Ui: metaPtr.Ui,
|
||||
}, nil
|
||||
},
|
||||
|
||||
"plugin-exec": func() (cli.Command, error) {
|
||||
return &command.PluginExec{
|
||||
Meta: *metaPtr,
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@@ -1,66 +0,0 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/vault/helper/builtinplugins"
|
||||
"github.com/hashicorp/vault/meta"
|
||||
)
|
||||
|
||||
type PluginExec struct {
|
||||
meta.Meta
|
||||
}
|
||||
|
||||
func (c *PluginExec) Run(args []string) int {
|
||||
flags := c.Meta.FlagSet("plugin-exec", meta.FlagSetDefault)
|
||||
flags.Usage = func() { c.Ui.Error(c.Help()) }
|
||||
if err := flags.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
args = flags.Args()
|
||||
if len(args) != 1 {
|
||||
flags.Usage()
|
||||
c.Ui.Error(fmt.Sprintf(
|
||||
"\nplugin-exec expects one argument: the plugin to execute."))
|
||||
return 1
|
||||
}
|
||||
|
||||
pluginName := args[0]
|
||||
|
||||
runner, ok := builtinplugins.BuiltinPlugins.Get(pluginName)
|
||||
if !ok {
|
||||
c.Ui.Error(fmt.Sprintf(
|
||||
"No plugin with the name %s found", pluginName))
|
||||
return 1
|
||||
}
|
||||
|
||||
err := runner()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf(
|
||||
"Error running plugin: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *PluginExec) Synopsis() string {
|
||||
return "Runs a builtin plugin. Should only be called by vault."
|
||||
}
|
||||
|
||||
func (c *PluginExec) Help() string {
|
||||
helpText := `
|
||||
Usage: vault plugin-exec type
|
||||
|
||||
Runs a builtin plugin. Should only be called by vault.
|
||||
|
||||
This will execute a plugin for use in a plugable location in vault. If run by
|
||||
a cli user it will print a message indicating it can not be executed by anyone
|
||||
other than vault. For supported plugin types see the vault documentation.
|
||||
|
||||
General Options:
|
||||
` + meta.GeneralOptionsUsage()
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
@@ -1,10 +1,8 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -133,33 +131,6 @@ func (c *ServerCommand) Run(args []string) int {
|
||||
dev = true
|
||||
}
|
||||
|
||||
// Record the vault binary's location and SHA-256 checksum for use in
|
||||
// builtin plugins.
|
||||
ex, err := os.Executable()
|
||||
if err != nil {
|
||||
c.Ui.Output(fmt.Sprintf(
|
||||
"Error looking up vault binary: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
file, err := os.Open(ex)
|
||||
if err != nil {
|
||||
c.Ui.Output(fmt.Sprintf(
|
||||
"Error loading vault binary: %s", err))
|
||||
return 1
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
hash := sha256.New()
|
||||
_, err = io.Copy(hash, file)
|
||||
if err != nil {
|
||||
c.Ui.Output(fmt.Sprintf(
|
||||
"Error checksumming vault binary: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
sha256Value := hash.Sum(nil)
|
||||
|
||||
// Validation
|
||||
if !dev {
|
||||
switch {
|
||||
@@ -269,8 +240,6 @@ func (c *ServerCommand) Run(args []string) int {
|
||||
ClusterName: config.ClusterName,
|
||||
CacheSize: config.CacheSize,
|
||||
PluginDirectory: config.PluginDirectory,
|
||||
VaultBinaryLocation: ex,
|
||||
VaultBinarySHA256: sha256Value,
|
||||
}
|
||||
if dev {
|
||||
coreConfig.DevToken = devRootTokenID
|
||||
|
@@ -5,20 +5,22 @@ import (
|
||||
"github.com/hashicorp/vault/plugins/database/postgresql"
|
||||
)
|
||||
|
||||
type BuiltinFactory func() (interface{}, error)
|
||||
|
||||
var BuiltinPlugins *builtinPlugins = &builtinPlugins{
|
||||
plugins: map[string]func() error{
|
||||
"mysql-database-plugin": mysql.Run,
|
||||
"postgresql-database-plugin": postgresql.Run,
|
||||
plugins: 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]func() error
|
||||
plugins map[string]BuiltinFactory
|
||||
}
|
||||
|
||||
func (b *builtinPlugins) Get(name string) (func() error, bool) {
|
||||
func (b *builtinPlugins) Get(name string) (BuiltinFactory, bool) {
|
||||
f, ok := b.plugins[name]
|
||||
return f, ok
|
||||
}
|
||||
|
@@ -45,6 +45,7 @@ type PluginRunner struct {
|
||||
Args []string `json:"args"`
|
||||
Sha256 []byte `json:"sha256"`
|
||||
Builtin bool `json:"builtin"`
|
||||
BuiltinFactory func() (interface{}, error) `json:"-"`
|
||||
}
|
||||
|
||||
// Run takes a wrapper instance, and the go-plugin paramaters and executes a
|
||||
|
@@ -23,7 +23,7 @@ type MySQL struct {
|
||||
credsutil.CredentialsProducer
|
||||
}
|
||||
|
||||
func New() *MySQL {
|
||||
func New() (interface{}, error) {
|
||||
connProducer := &connutil.SQLConnectionProducer{}
|
||||
connProducer.Type = mySQLTypeName
|
||||
|
||||
@@ -37,14 +37,17 @@ func New() *MySQL {
|
||||
CredentialsProducer: credsProducer,
|
||||
}
|
||||
|
||||
return dbType
|
||||
return dbType, nil
|
||||
}
|
||||
|
||||
// Run instantiates a MySQL object, and runs the RPC server for the plugin
|
||||
func Run() error {
|
||||
dbType := New()
|
||||
dbType, err := New()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dbplugin.NewPluginServer(dbType)
|
||||
dbplugin.NewPluginServer(dbType.(*MySQL))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@@ -66,7 +66,8 @@ func TestMySQL_Initialize(t *testing.T) {
|
||||
"connection_url": connURL,
|
||||
}
|
||||
|
||||
db := New()
|
||||
dbRaw, _ := New()
|
||||
db := dbRaw.(*MySQL)
|
||||
connProducer := db.ConnectionProducer.(*connutil.SQLConnectionProducer)
|
||||
|
||||
err := db.Initialize(connectionDetails, true)
|
||||
@@ -92,7 +93,8 @@ func TestMySQL_CreateUser(t *testing.T) {
|
||||
"connection_url": connURL,
|
||||
}
|
||||
|
||||
db := New()
|
||||
dbRaw, _ := New()
|
||||
db := dbRaw.(*MySQL)
|
||||
|
||||
err := db.Initialize(connectionDetails, true)
|
||||
if err != nil {
|
||||
@@ -127,7 +129,8 @@ func TestMySQL_RevokeUser(t *testing.T) {
|
||||
"connection_url": connURL,
|
||||
}
|
||||
|
||||
db := New()
|
||||
dbRaw, _ := New()
|
||||
db := dbRaw.(*MySQL)
|
||||
|
||||
err := db.Initialize(connectionDetails, true)
|
||||
if err != nil {
|
||||
|
@@ -16,7 +16,8 @@ import (
|
||||
|
||||
const postgreSQLTypeName string = "postgres"
|
||||
|
||||
func New() *PostgreSQL {
|
||||
// New implements builtinplugins.BuiltinFactory
|
||||
func New() (interface{}, error) {
|
||||
connProducer := &connutil.SQLConnectionProducer{}
|
||||
connProducer.Type = postgreSQLTypeName
|
||||
|
||||
@@ -30,14 +31,17 @@ func New() *PostgreSQL {
|
||||
CredentialsProducer: credsProducer,
|
||||
}
|
||||
|
||||
return dbType
|
||||
return dbType, nil
|
||||
}
|
||||
|
||||
// Run instatiates a PostgreSQL object, and runs the RPC server for the plugin
|
||||
func Run() error {
|
||||
dbType := New()
|
||||
dbType, err := New()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dbplugin.NewPluginServer(dbType)
|
||||
dbplugin.NewPluginServer(dbType.(*PostgreSQL))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@@ -66,7 +66,9 @@ func TestPostgreSQL_Initialize(t *testing.T) {
|
||||
"connection_url": connURL,
|
||||
}
|
||||
|
||||
db := New()
|
||||
dbRaw, _ := New()
|
||||
db := dbRaw.(*PostgreSQL)
|
||||
|
||||
connProducer := db.ConnectionProducer.(*connutil.SQLConnectionProducer)
|
||||
|
||||
err := db.Initialize(connectionDetails, true)
|
||||
@@ -92,7 +94,8 @@ func TestPostgreSQL_CreateUser(t *testing.T) {
|
||||
"connection_url": connURL,
|
||||
}
|
||||
|
||||
db := New()
|
||||
dbRaw, _ := New()
|
||||
db := dbRaw.(*PostgreSQL)
|
||||
err := db.Initialize(connectionDetails, true)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
@@ -136,7 +139,8 @@ func TestPostgreSQL_RenewUser(t *testing.T) {
|
||||
"connection_url": connURL,
|
||||
}
|
||||
|
||||
db := New()
|
||||
dbRaw, _ := New()
|
||||
db := dbRaw.(*PostgreSQL)
|
||||
err := db.Initialize(connectionDetails, true)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
@@ -176,7 +180,8 @@ func TestPostgreSQL_RevokeUser(t *testing.T) {
|
||||
"connection_url": connURL,
|
||||
}
|
||||
|
||||
db := New()
|
||||
dbRaw, _ := New()
|
||||
db := dbRaw.(*PostgreSQL)
|
||||
err := db.Initialize(connectionDetails, true)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
@@ -335,12 +335,6 @@ type Core struct {
|
||||
// pluginDirectory is the location vault will look for plugin binaries
|
||||
pluginDirectory string
|
||||
|
||||
// vaultBinaryLocation is used to run builtin plugins in secure mode
|
||||
vaultBinaryLocation string
|
||||
|
||||
// vaultBinarySHA256 is used to run builtin plugins in secure mode
|
||||
vaultBinarySHA256 []byte
|
||||
|
||||
// pluginCatalog is used to manage plugin configurations
|
||||
pluginCatalog *PluginCatalog
|
||||
|
||||
@@ -390,8 +384,6 @@ type CoreConfig struct {
|
||||
EnableUI bool `json:"ui" structs:"ui" mapstructure:"ui"`
|
||||
|
||||
PluginDirectory string `json:"plugin_directory" structs:"plugin_directory" mapstructure:"plugin_directory"`
|
||||
VaultBinaryLocation string `json:"vault_binary_location" structs:"vault_binary_location" mapstructure:"vault_binary_location"`
|
||||
VaultBinarySHA256 []byte `json:"vault_binary_sha256" structs:"vault_binary_sha256" mapstructure:"vault_binary_sha256"`
|
||||
|
||||
ReloadFuncs *map[string][]ReloadFunc
|
||||
ReloadFuncsLock *sync.RWMutex
|
||||
@@ -449,8 +441,6 @@ func NewCore(conf *CoreConfig) (*Core, error) {
|
||||
clusterName: conf.ClusterName,
|
||||
clusterListenerShutdownCh: make(chan struct{}),
|
||||
clusterListenerShutdownSuccessCh: make(chan struct{}),
|
||||
vaultBinaryLocation: conf.VaultBinaryLocation,
|
||||
vaultBinarySHA256: conf.VaultBinarySHA256,
|
||||
disableMlock: conf.DisableMlock,
|
||||
}
|
||||
|
||||
|
@@ -25,8 +25,6 @@ var (
|
||||
type PluginCatalog struct {
|
||||
catalogView *BarrierView
|
||||
directory string
|
||||
vaultCommand string
|
||||
vaultSHA256 []byte
|
||||
|
||||
lock sync.RWMutex
|
||||
}
|
||||
@@ -35,8 +33,6 @@ func (c *Core) setupPluginCatalog() error {
|
||||
c.pluginCatalog = &PluginCatalog{
|
||||
catalogView: c.systemBarrierView.SubView(pluginCatalogPrefix),
|
||||
directory: c.pluginDirectory,
|
||||
vaultCommand: c.vaultBinaryLocation,
|
||||
vaultSHA256: c.vaultBinarySHA256,
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -64,17 +60,15 @@ func (c *PluginCatalog) Get(name string) (*pluginutil.PluginRunner, error) {
|
||||
}
|
||||
|
||||
// Look for builtin plugins
|
||||
if _, ok := builtinplugins.BuiltinPlugins.Get(name); !ok {
|
||||
return nil, fmt.Errorf("no plugin found with name: %s", name)
|
||||
}
|
||||
|
||||
if factory, ok := builtinplugins.BuiltinPlugins.Get(name); ok {
|
||||
return &pluginutil.PluginRunner{
|
||||
Name: name,
|
||||
Command: c.vaultCommand,
|
||||
Args: []string{"plugin-exec", name},
|
||||
Sha256: c.vaultSHA256,
|
||||
Builtin: true,
|
||||
BuiltinFactory: factory,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("no plugin found with name: %s", name)
|
||||
}
|
||||
|
||||
// Set registers a new external plugin with the catalog, or updates an existing
|
||||
|
Reference in New Issue
Block a user