open-vault/vault/mount_test.go

353 lines
6.9 KiB
Go
Raw Normal View History

2015-03-11 22:33:25 +00:00
package vault
import (
"reflect"
"testing"
2015-04-02 18:47:44 +00:00
"time"
"github.com/hashicorp/vault/logical"
2015-03-11 22:33:25 +00:00
)
func TestCore_DefaultMountTable(t *testing.T) {
2015-03-29 23:18:08 +00:00
c, key, _ := TestCoreUnsealed(t)
2015-03-11 22:33:25 +00:00
verifyDefaultTable(t, c.mounts)
// Start a second core with same physical
2015-04-29 01:12:57 +00:00
conf := &CoreConfig{
Physical: c.physical,
DisableMlock: true,
}
2015-03-11 22:33:25 +00:00
c2, err := NewCore(conf)
if err != nil {
2015-03-12 01:29:49 +00:00
t.Fatalf("err: %v", err)
}
unseal, err := c2.Unseal(key)
if err != nil {
t.Fatalf("err: %v", err)
}
if !unseal {
t.Fatalf("should be unsealed")
}
// Verify matching mount tables
if !reflect.DeepEqual(c.mounts, c2.mounts) {
t.Fatalf("mismatch: %v %v", c.mounts, c2.mounts)
}
}
func TestCore_Mount(t *testing.T) {
2015-03-29 23:18:08 +00:00
c, key, _ := TestCoreUnsealed(t)
2015-03-12 01:29:49 +00:00
me := &MountEntry{
Path: "foo",
Type: "generic",
}
err := c.mount(me)
2015-03-12 01:29:49 +00:00
if err != nil {
t.Fatalf("err: %v", err)
}
match := c.router.MatchingMount("foo/bar")
if match != "foo/" {
t.Fatalf("missing mount")
}
2015-04-29 01:12:57 +00:00
conf := &CoreConfig{
Physical: c.physical,
DisableMlock: true,
}
2015-03-12 01:29:49 +00:00
c2, err := NewCore(conf)
if err != nil {
t.Fatalf("err: %v", err)
}
unseal, err := c2.Unseal(key)
if err != nil {
t.Fatalf("err: %v", err)
}
if !unseal {
t.Fatalf("should be unsealed")
}
// Verify matching mount tables
if !reflect.DeepEqual(c.mounts, c2.mounts) {
t.Fatalf("mismatch: %v %v", c.mounts, c2.mounts)
}
}
func TestCore_Unmount(t *testing.T) {
2015-03-29 23:18:08 +00:00
c, key, _ := TestCoreUnsealed(t)
err := c.unmount("secret")
2015-03-12 01:29:49 +00:00
if err != nil {
t.Fatalf("err: %v", err)
}
match := c.router.MatchingMount("secret/foo")
if match != "" {
t.Fatalf("backend present")
}
2015-04-29 01:12:57 +00:00
conf := &CoreConfig{
Physical: c.physical,
DisableMlock: true,
}
2015-03-12 01:29:49 +00:00
c2, err := NewCore(conf)
if err != nil {
2015-03-11 22:33:25 +00:00
t.Fatalf("err: %v", err)
}
unseal, err := c2.Unseal(key)
if err != nil {
t.Fatalf("err: %v", err)
}
if !unseal {
t.Fatalf("should be unsealed")
}
// Verify matching mount tables
if !reflect.DeepEqual(c.mounts, c2.mounts) {
t.Fatalf("mismatch: %v %v", c.mounts, c2.mounts)
}
}
2015-04-02 18:47:44 +00:00
func TestCore_Unmount_Cleanup(t *testing.T) {
noop := &NoopBackend{}
c, _, root := TestCoreUnsealed(t)
c.logicalBackends["noop"] = func(map[string]string) (logical.Backend, error) {
return noop, nil
}
// Mount the noop backend
me := &MountEntry{
Path: "test/",
Type: "noop",
}
if err := c.mount(me); err != nil {
t.Fatalf("err: %v", err)
}
// Store the view
view := c.router.MatchingView("test/")
// Inject data
se := &logical.StorageEntry{
Key: "plstodelete",
Value: []byte("test"),
}
if err := view.Put(se); err != nil {
t.Fatalf("err: %v", err)
}
// Setup response
resp := &logical.Response{
Secret: &logical.Secret{
LeaseOptions: logical.LeaseOptions{
Lease: time.Hour,
},
2015-04-02 18:47:44 +00:00
},
Data: map[string]interface{}{
"foo": "bar",
},
}
noop.Response = resp
// Generate leased secret
r := &logical.Request{
Operation: logical.ReadOperation,
Path: "test/foo",
ClientToken: root,
}
resp, err := c.HandleRequest(r)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp.Secret.LeaseID == "" {
2015-04-02 18:47:44 +00:00
t.Fatalf("bad: %#v", resp)
}
// Unmount, this should cleanup
if err := c.unmount("test/"); err != nil {
t.Fatalf("err: %v", err)
}
// Rollback should be invoked
if noop.Requests[1].Operation != logical.RollbackOperation {
t.Fatalf("bad: %#v", noop.Requests)
}
// Revoke should be invoked
if noop.Requests[2].Operation != logical.RevokeOperation {
t.Fatalf("bad: %#v", noop.Requests)
}
if noop.Requests[2].Path != "foo" {
t.Fatalf("bad: %#v", noop.Requests)
}
// View should be empty
out, err := CollectKeys(view)
if err != nil {
t.Fatalf("err: %v", err)
}
if len(out) != 0 {
t.Fatalf("bad: %#v", out)
}
}
func TestCore_Remount(t *testing.T) {
2015-03-29 23:18:08 +00:00
c, key, _ := TestCoreUnsealed(t)
err := c.remount("secret", "foo")
2015-03-12 19:09:30 +00:00
if err != nil {
t.Fatalf("err: %v", err)
}
match := c.router.MatchingMount("foo/bar")
if match != "foo/" {
t.Fatalf("failed remount")
}
2015-04-29 01:12:57 +00:00
conf := &CoreConfig{
Physical: c.physical,
DisableMlock: true,
}
2015-03-12 19:09:30 +00:00
c2, err := NewCore(conf)
if err != nil {
t.Fatalf("err: %v", err)
}
unseal, err := c2.Unseal(key)
if err != nil {
t.Fatalf("err: %v", err)
}
if !unseal {
t.Fatalf("should be unsealed")
}
// Verify matching mount tables
if !reflect.DeepEqual(c.mounts, c2.mounts) {
t.Fatalf("mismatch: %v %v", c.mounts, c2.mounts)
}
}
2015-04-02 19:04:37 +00:00
func TestCore_Remount_Cleanup(t *testing.T) {
noop := &NoopBackend{}
c, _, root := TestCoreUnsealed(t)
c.logicalBackends["noop"] = func(map[string]string) (logical.Backend, error) {
return noop, nil
}
// Mount the noop backend
me := &MountEntry{
Path: "test/",
Type: "noop",
}
if err := c.mount(me); err != nil {
t.Fatalf("err: %v", err)
}
// Store the view
view := c.router.MatchingView("test/")
// Inject data
se := &logical.StorageEntry{
Key: "plstokeep",
Value: []byte("test"),
}
if err := view.Put(se); err != nil {
t.Fatalf("err: %v", err)
}
// Setup response
resp := &logical.Response{
Secret: &logical.Secret{
LeaseOptions: logical.LeaseOptions{
Lease: time.Hour,
},
2015-04-02 19:04:37 +00:00
},
Data: map[string]interface{}{
"foo": "bar",
},
}
noop.Response = resp
// Generate leased secret
r := &logical.Request{
Operation: logical.ReadOperation,
Path: "test/foo",
ClientToken: root,
}
resp, err := c.HandleRequest(r)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp.Secret.LeaseID == "" {
2015-04-02 19:04:37 +00:00
t.Fatalf("bad: %#v", resp)
}
// Remount, this should cleanup
if err := c.remount("test/", "new/"); err != nil {
t.Fatalf("err: %v", err)
}
// Rollback should be invoked
if noop.Requests[1].Operation != logical.RollbackOperation {
t.Fatalf("bad: %#v", noop.Requests)
}
// Revoke should be invoked
if noop.Requests[2].Operation != logical.RevokeOperation {
t.Fatalf("bad: %#v", noop.Requests)
}
if noop.Requests[2].Path != "foo" {
t.Fatalf("bad: %#v", noop.Requests)
}
// View should not be empty
out, err := CollectKeys(view)
if err != nil {
t.Fatalf("err: %v", err)
}
if len(out) != 1 && out[0] != "plstokeep" {
t.Fatalf("bad: %#v", out)
}
}
func TestCore_Remount_Protected(t *testing.T) {
2015-03-29 23:18:08 +00:00
c, _, _ := TestCoreUnsealed(t)
err := c.remount("sys", "foo")
2015-03-12 19:09:30 +00:00
if err.Error() != "cannot remount 'sys/'" {
t.Fatalf("err: %v", err)
}
}
2015-03-11 22:33:25 +00:00
func TestDefaultMountTable(t *testing.T) {
table := defaultMountTable()
verifyDefaultTable(t, table)
}
func verifyDefaultTable(t *testing.T, table *MountTable) {
if len(table.Entries) != 2 {
t.Fatalf("bad: %v", table.Entries)
}
for idx, entry := range table.Entries {
switch idx {
case 0:
if entry.Path != "secret/" {
t.Fatalf("bad: %v", entry)
}
if entry.Type != "generic" {
t.Fatalf("bad: %v", entry)
}
case 1:
if entry.Path != "sys/" {
t.Fatalf("bad: %v", entry)
}
if entry.Type != "system" {
t.Fatalf("bad: %v", entry)
}
}
if entry.Description == "" {
t.Fatalf("bad: %v", entry)
}
if entry.UUID == "" {
t.Fatalf("bad: %v", entry)
}
}
}