vault: Loading mount tables on start
This commit is contained in:
parent
370693ebb4
commit
f54e4e0f6a
|
@ -87,6 +87,10 @@ type Core struct {
|
|||
// the threshold number of parts is available.
|
||||
unlockParts [][]byte
|
||||
|
||||
// mounts is loaded after unseal since it is a protected
|
||||
// configuration
|
||||
mounts *MountTable
|
||||
|
||||
logger *log.Logger
|
||||
}
|
||||
|
||||
|
@ -339,6 +343,13 @@ func (c *Core) Unseal(key []byte) (bool, error) {
|
|||
return false, err
|
||||
}
|
||||
|
||||
// Do post-unseal setup
|
||||
if err := c.postUnseal(); err != nil {
|
||||
c.logger.Printf("[ERR] core: post-unseal setup failed: %v", err)
|
||||
c.barrier.Seal()
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Success!
|
||||
c.logger.Printf("[INFO] core: vault is unsealed")
|
||||
c.sealed = false
|
||||
|
@ -357,3 +368,14 @@ func (c *Core) Seal() error {
|
|||
c.sealed = true
|
||||
return c.barrier.Seal()
|
||||
}
|
||||
|
||||
// postUnseal is invoked after the barrier is unsealed, but before
|
||||
// allowing any user operations. This allows us to setup any state that
|
||||
// requires the Vault to be unsealed such as mount tables, logical backends,
|
||||
// credential stores, etc.
|
||||
func (c *Core) postUnseal() error {
|
||||
if err := c.loadMounts(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -279,7 +279,7 @@ func TestCore_Route_Sealed(t *testing.T) {
|
|||
// Should not route anything
|
||||
req := &Request{
|
||||
Operation: ReadOperation,
|
||||
Path: "sys/test",
|
||||
Path: "sys/mounts",
|
||||
}
|
||||
_, err := c.HandleRequest(req)
|
||||
if err != ErrSealed {
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
package vault
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
)
|
||||
|
||||
const (
|
||||
// coreMountConfigPath is used to store the mount configuration.
|
||||
// Mounts are protected within the Vault itself, which means they
|
||||
// can only be viewed or modified after an unseal.
|
||||
coreMountConfigPath = "core/mounts"
|
||||
)
|
||||
|
||||
// MountTable is used to represent the internal mount table
|
||||
type MountTable struct {
|
||||
Entries []*MountEntry `json:"entries"`
|
||||
}
|
||||
|
||||
// MountEntry is used to represent a mount table entry
|
||||
type MountEntry struct {
|
||||
Path string `json:"path"` // Mount Path
|
||||
Type string `json:"type"` // Logical backend Type
|
||||
Description string `json:"description"` // User-provided description
|
||||
UUID string `json:"uuid"` // Barrier view UUID
|
||||
}
|
||||
|
||||
// loadMounts is invoked as part of postUnseal to load the mount table
|
||||
func (c *Core) loadMounts() error {
|
||||
// Load the existing mount table
|
||||
raw, err := c.barrier.Get(coreMountConfigPath)
|
||||
if err != nil {
|
||||
c.logger.Printf("[ERR] core: failed to read mount table: %v", err)
|
||||
return errors.New("failed to setup mount table")
|
||||
}
|
||||
if raw != nil {
|
||||
if err := json.Unmarshal(raw.Value, c.mounts); err != nil {
|
||||
c.logger.Printf("[ERR] core: failed to decode mount table: %v", err)
|
||||
return errors.New("failed to setup mount table")
|
||||
}
|
||||
}
|
||||
|
||||
// Done if we have restored the mount table
|
||||
if c.mounts != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create and persist the default mount table
|
||||
c.mounts = defaultMountTable()
|
||||
if err := c.persistMounts(); err != nil {
|
||||
return errors.New("failed to setup mount table")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// persistMounts is used to persist the mount table after modification
|
||||
func (c *Core) persistMounts() error {
|
||||
// Marshal the table
|
||||
raw, err := json.Marshal(c.mounts)
|
||||
if err != nil {
|
||||
c.logger.Printf("[ERR] core: failed to encode mount table: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Create an entry
|
||||
entry := &Entry{
|
||||
Key: coreMountConfigPath,
|
||||
Value: raw,
|
||||
}
|
||||
|
||||
// Write to the physical backend
|
||||
if err := c.barrier.Put(entry); err != nil {
|
||||
c.logger.Printf("[ERR] core: failed to persist mount table: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// defaultMountTable creates a default mount table
|
||||
func defaultMountTable() *MountTable {
|
||||
table := &MountTable{}
|
||||
genericMount := &MountEntry{
|
||||
Path: "secret/",
|
||||
Type: "generic",
|
||||
Description: "generic secret storage",
|
||||
UUID: generateUUID(),
|
||||
}
|
||||
sysMount := &MountEntry{
|
||||
Path: "sys/",
|
||||
Type: "system",
|
||||
Description: "system endpoints used for control, policy and debugging",
|
||||
UUID: generateUUID(),
|
||||
}
|
||||
table.Entries = append(table.Entries, genericMount)
|
||||
table.Entries = append(table.Entries, sysMount)
|
||||
return table
|
||||
}
|
Loading…
Reference in New Issue