open-vault/vault/cluster.go

100 lines
2.5 KiB
Go
Raw Normal View History

package vault
import (
"encoding/json"
"fmt"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/helper/jsonutil"
)
const (
// Storage path where the local cluster name and identifier are stored
coreLocalClusterPath = "core/cluster/local"
)
// Structure representing the storage entry that holds cluster information
type Cluster struct {
// Name of the cluster
Name string `json:"name" structs:"name" mapstructure:"name"`
// Identifier of the cluster
ID string `json:"id" structs:"id" mapstructure:"id"`
}
// Cluster fetches the details of either local or global cluster based on the
// input. This method errors out when Vault is sealed.
2016-07-26 13:18:38 +00:00
func (c *Core) Cluster() (*Cluster, error) {
// Fetch the storage entry. This call fails when Vault is sealed.
entry, err := c.barrier.Get(coreLocalClusterPath)
if err != nil {
return nil, err
}
if entry == nil {
return nil, nil
}
// Decode the cluster information
var cluster Cluster
if err = jsonutil.DecodeJSON(entry.Value, &cluster); err != nil {
return nil, fmt.Errorf("failed to decode cluster details: %v", err)
}
// Set in config file
if c.clusterName != "" {
cluster.Name = c.clusterName
}
return &cluster, nil
}
// setupCluster creates storage entries for holding Vault cluster information.
2016-07-26 13:18:38 +00:00
// Entries will be created only if they are not already present. If clusterName
// is not supplied, this method will auto-generate it.
func (c *Core) setupCluster() error {
// Check if storage index is already present or not
2016-07-26 13:18:38 +00:00
cluster, err := c.Cluster()
if err != nil {
c.logger.Printf("[ERR] core: failed to get cluster details: %v", err)
return err
}
if cluster != nil {
// If index is already present, don't update it
return nil
}
2016-07-26 13:18:38 +00:00
// If cluster name is not supplied, generate one
if c.clusterName == "" {
clusterNameBytes, err := uuid.GenerateRandomBytes(4)
if err != nil {
c.logger.Printf("[ERR] core: failed to generate cluster name: %v", err)
return err
}
2016-07-26 18:05:27 +00:00
c.clusterName = fmt.Sprintf("vault-cluster-%08x", clusterNameBytes)
}
2016-07-26 13:18:38 +00:00
// Generate a clusterID
clusterID, err := uuid.GenerateUUID()
if err != nil {
c.logger.Printf("[ERR] core: failed to generate cluster identifier: %v", err)
return err
}
// Encode the cluster information into as a JSON string
rawCluster, err := json.Marshal(&Cluster{
2016-07-26 13:18:38 +00:00
Name: c.clusterName,
ID: clusterID,
})
if err != nil {
c.logger.Printf("[ERR] core: failed to encode cluster details: %v", err)
return err
}
// Store it
return c.barrier.Put(&Entry{
Key: coreLocalClusterPath,
Value: rawCluster,
})
2016-07-26 13:18:38 +00:00
}