2017-04-12 16:40:54 +00:00
|
|
|
package vault
|
|
|
|
|
|
|
|
import (
|
2018-01-19 06:44:44 +00:00
|
|
|
"context"
|
2017-04-12 16:40:54 +00:00
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"reflect"
|
|
|
|
"sort"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/hashicorp/vault/helper/builtinplugins"
|
2018-11-07 01:21:24 +00:00
|
|
|
"github.com/hashicorp/vault/helper/consts"
|
2017-04-12 16:40:54 +00:00
|
|
|
"github.com/hashicorp/vault/helper/pluginutil"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestPluginCatalog_CRUD(t *testing.T) {
|
|
|
|
core, _, _ := TestCoreUnsealed(t)
|
|
|
|
|
|
|
|
sym, err := filepath.EvalSymlinks(os.TempDir())
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error: %v", err)
|
|
|
|
}
|
|
|
|
core.pluginCatalog.directory = sym
|
|
|
|
|
|
|
|
// Get builtin plugin
|
2018-11-07 01:21:24 +00:00
|
|
|
p, err := core.pluginCatalog.Get(context.Background(), "mysql-database-plugin", consts.PluginTypeDatabase)
|
2017-04-12 16:40:54 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
expectedBuiltin := &pluginutil.PluginRunner{
|
|
|
|
Name: "mysql-database-plugin",
|
2018-11-07 01:21:24 +00:00
|
|
|
Type: consts.PluginTypeDatabase,
|
2017-04-12 16:40:54 +00:00
|
|
|
Builtin: true,
|
|
|
|
}
|
2018-11-07 01:21:24 +00:00
|
|
|
expectedBuiltin.BuiltinFactory, _ = builtinplugins.Registry.Get("mysql-database-plugin", consts.PluginTypeDatabase)
|
2017-04-12 16:40:54 +00:00
|
|
|
|
2017-04-21 17:24:34 +00:00
|
|
|
if &(p.BuiltinFactory) == &(expectedBuiltin.BuiltinFactory) {
|
|
|
|
t.Fatal("expected BuiltinFactory did not match actual")
|
|
|
|
}
|
|
|
|
expectedBuiltin.BuiltinFactory = nil
|
|
|
|
p.BuiltinFactory = nil
|
2017-04-12 16:40:54 +00:00
|
|
|
if !reflect.DeepEqual(p, expectedBuiltin) {
|
|
|
|
t.Fatalf("expected did not match actual, got %#v\n expected %#v\n", p, expectedBuiltin)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set a plugin, test overwriting a builtin plugin
|
|
|
|
file, err := ioutil.TempFile(os.TempDir(), "temp")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
|
2018-01-18 00:19:28 +00:00
|
|
|
command := fmt.Sprintf("%s", filepath.Base(file.Name()))
|
2018-11-07 01:21:24 +00:00
|
|
|
err = core.pluginCatalog.Set(context.Background(), "mysql-database-plugin", consts.PluginTypeDatabase, command, []string{"--test"}, []string{"FOO=BAR"}, []byte{'1'})
|
2017-04-12 16:40:54 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the plugin
|
2018-11-07 01:21:24 +00:00
|
|
|
p, err = core.pluginCatalog.Get(context.Background(), "mysql-database-plugin", consts.PluginTypeDatabase)
|
2017-04-12 16:40:54 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
expected := &pluginutil.PluginRunner{
|
|
|
|
Name: "mysql-database-plugin",
|
2018-11-07 01:21:24 +00:00
|
|
|
Type: consts.PluginTypeDatabase,
|
2017-04-12 16:40:54 +00:00
|
|
|
Command: filepath.Join(sym, filepath.Base(file.Name())),
|
|
|
|
Args: []string{"--test"},
|
2018-09-20 17:50:29 +00:00
|
|
|
Env: []string{"FOO=BAR"},
|
2017-04-12 16:40:54 +00:00
|
|
|
Sha256: []byte{'1'},
|
|
|
|
Builtin: false,
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(p, expected) {
|
|
|
|
t.Fatalf("expected did not match actual, got %#v\n expected %#v\n", p, expected)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete the plugin
|
2018-11-07 01:21:24 +00:00
|
|
|
err = core.pluginCatalog.Delete(context.Background(), "mysql-database-plugin", consts.PluginTypeDatabase)
|
2017-04-12 16:40:54 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get builtin plugin
|
2018-11-07 01:21:24 +00:00
|
|
|
p, err = core.pluginCatalog.Get(context.Background(), "mysql-database-plugin", consts.PluginTypeDatabase)
|
2017-04-12 16:40:54 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error %v", err)
|
|
|
|
}
|
|
|
|
|
2017-04-21 17:24:34 +00:00
|
|
|
expectedBuiltin = &pluginutil.PluginRunner{
|
|
|
|
Name: "mysql-database-plugin",
|
2018-11-07 01:21:24 +00:00
|
|
|
Type: consts.PluginTypeDatabase,
|
2017-04-21 17:24:34 +00:00
|
|
|
Builtin: true,
|
|
|
|
}
|
2018-11-07 01:21:24 +00:00
|
|
|
expectedBuiltin.BuiltinFactory, _ = builtinplugins.Registry.Get("mysql-database-plugin", consts.PluginTypeDatabase)
|
2017-04-21 17:24:34 +00:00
|
|
|
|
|
|
|
if &(p.BuiltinFactory) == &(expectedBuiltin.BuiltinFactory) {
|
|
|
|
t.Fatal("expected BuiltinFactory did not match actual")
|
|
|
|
}
|
|
|
|
expectedBuiltin.BuiltinFactory = nil
|
|
|
|
p.BuiltinFactory = nil
|
2017-04-12 16:40:54 +00:00
|
|
|
if !reflect.DeepEqual(p, expectedBuiltin) {
|
|
|
|
t.Fatalf("expected did not match actual, got %#v\n expected %#v\n", p, expectedBuiltin)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPluginCatalog_List(t *testing.T) {
|
|
|
|
core, _, _ := TestCoreUnsealed(t)
|
|
|
|
|
|
|
|
sym, err := filepath.EvalSymlinks(os.TempDir())
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error: %v", err)
|
|
|
|
}
|
|
|
|
core.pluginCatalog.directory = sym
|
|
|
|
|
|
|
|
// Get builtin plugins and sort them
|
2018-11-07 01:21:24 +00:00
|
|
|
builtinKeys := builtinplugins.Registry.Keys(consts.PluginTypeDatabase)
|
2017-04-12 16:40:54 +00:00
|
|
|
sort.Strings(builtinKeys)
|
|
|
|
|
|
|
|
// List only builtin plugins
|
2018-11-07 01:21:24 +00:00
|
|
|
plugins, err := core.pluginCatalog.List(context.Background(), consts.PluginTypeDatabase)
|
2017-04-12 16:40:54 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(plugins) != len(builtinKeys) {
|
|
|
|
t.Fatalf("unexpected length of plugin list, expected %d, got %d", len(builtinKeys), len(plugins))
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, p := range builtinKeys {
|
|
|
|
if !reflect.DeepEqual(plugins[i], p) {
|
|
|
|
t.Fatalf("expected did not match actual, got %#v\n expected %#v\n", plugins[i], p)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set a plugin, test overwriting a builtin plugin
|
|
|
|
file, err := ioutil.TempFile(os.TempDir(), "temp")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
|
2018-01-18 00:19:28 +00:00
|
|
|
command := filepath.Base(file.Name())
|
2018-11-07 01:21:24 +00:00
|
|
|
err = core.pluginCatalog.Set(context.Background(), "mysql-database-plugin", consts.PluginTypeDatabase, command, []string{"--test"}, []string{}, []byte{'1'})
|
2017-04-12 16:40:54 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set another plugin
|
2018-11-07 01:21:24 +00:00
|
|
|
err = core.pluginCatalog.Set(context.Background(), "aaaaaaa", consts.PluginTypeDatabase, command, []string{"--test"}, []string{}, []byte{'1'})
|
2017-04-12 16:40:54 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// List the plugins
|
2018-11-07 01:21:24 +00:00
|
|
|
plugins, err = core.pluginCatalog.List(context.Background(), consts.PluginTypeDatabase)
|
2017-04-12 16:40:54 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error %v", err)
|
|
|
|
}
|
|
|
|
|
2018-11-07 01:21:24 +00:00
|
|
|
// plugins has a test-added plugin called "aaaaaaa" that is not built in
|
2017-04-12 16:40:54 +00:00
|
|
|
if len(plugins) != len(builtinKeys)+1 {
|
|
|
|
t.Fatalf("unexpected length of plugin list, expected %d, got %d", len(builtinKeys)+1, len(plugins))
|
|
|
|
}
|
|
|
|
|
|
|
|
// verify the first plugin is the one we just created.
|
|
|
|
if !reflect.DeepEqual(plugins[0], "aaaaaaa") {
|
|
|
|
t.Fatalf("expected did not match actual, got %#v\n expected %#v\n", plugins[0], "aaaaaaa")
|
|
|
|
}
|
|
|
|
|
2018-03-20 18:54:10 +00:00
|
|
|
// verify the builtin plugins are correct
|
2017-04-12 16:40:54 +00:00
|
|
|
for i, p := range builtinKeys {
|
|
|
|
if !reflect.DeepEqual(plugins[i+1], p) {
|
|
|
|
t.Fatalf("expected did not match actual, got %#v\n expected %#v\n", plugins[i+1], p)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|