119 lines
3 KiB
Go
119 lines
3 KiB
Go
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
|
|
coreLocalClusterInfoPath = "core/cluster/local/info"
|
|
)
|
|
|
|
// 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.
|
|
func (c *Core) Cluster() (*Cluster, error) {
|
|
var cluster Cluster
|
|
|
|
// Fetch the storage entry. This call fails when Vault is sealed.
|
|
entry, err := c.barrier.Get(coreLocalClusterInfoPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if entry == nil {
|
|
return &cluster, nil
|
|
}
|
|
|
|
// Decode the cluster information
|
|
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.
|
|
// 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
|
|
cluster, err := c.Cluster()
|
|
if err != nil {
|
|
c.logger.Printf("[ERR] core: failed to get cluster details: %v", err)
|
|
return err
|
|
}
|
|
|
|
if cluster == nil {
|
|
cluster = &Cluster{}
|
|
}
|
|
|
|
var modified bool
|
|
|
|
if cluster.Name == "" {
|
|
// If cluster name is not supplied, generate one
|
|
if c.clusterName == "" {
|
|
c.logger.Printf("[TRACE] core: cluster name not found/set, generating new")
|
|
clusterNameBytes, err := uuid.GenerateRandomBytes(4)
|
|
if err != nil {
|
|
c.logger.Printf("[ERR] core: failed to generate cluster name: %v", err)
|
|
return err
|
|
}
|
|
c.clusterName = fmt.Sprintf("vault-cluster-%08x", clusterNameBytes)
|
|
}
|
|
|
|
cluster.Name = c.clusterName
|
|
c.logger.Printf("[DEBUG] core: cluster name set to %s", cluster.Name)
|
|
modified = true
|
|
}
|
|
|
|
if cluster.ID == "" {
|
|
// Generate a clusterID
|
|
clusterID, err := uuid.GenerateUUID()
|
|
if err != nil {
|
|
c.logger.Printf("[ERR] core: failed to generate cluster identifier: %v", err)
|
|
return err
|
|
}
|
|
cluster.ID = clusterID
|
|
c.logger.Printf("[DEBUG] core: cluster ID set to %s", cluster.ID)
|
|
modified = true
|
|
}
|
|
|
|
if modified {
|
|
// Encode the cluster information into as a JSON string
|
|
rawCluster, err := json.Marshal(cluster)
|
|
if err != nil {
|
|
c.logger.Printf("[ERR] core: failed to encode cluster details: %v", err)
|
|
return err
|
|
}
|
|
|
|
// Store it
|
|
err = c.barrier.Put(&Entry{
|
|
Key: coreLocalClusterInfoPath,
|
|
Value: rawCluster,
|
|
})
|
|
if err != nil {
|
|
c.logger.Printf("[ERR] core: failed to store cluster details: %v", err)
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|