Merge pull request #1715 from hashicorp/fix-cluster-nil

Fix Cluster object being returned as nil when unsealed
This commit is contained in:
Vishal Nayak 2016-08-10 15:27:06 -04:00 committed by GitHub
commit eb752c42dc
3 changed files with 53 additions and 37 deletions

View File

@ -2,6 +2,7 @@ package http
import ( import (
"encoding/json" "encoding/json"
"fmt"
"net/http" "net/http"
"strconv" "strconv"
"time" "time"
@ -118,13 +119,11 @@ func getSysHealth(core *vault.Core, r *http.Request) (int, *HealthResponse, erro
var clusterName, clusterID string var clusterName, clusterID string
if !sealed { if !sealed {
cluster, err := core.Cluster() cluster, err := core.Cluster()
// Don't set the cluster details in the health status when Vault is sealed
if err != nil { if err != nil {
return http.StatusInternalServerError, nil, err return http.StatusInternalServerError, nil, err
} }
if cluster == nil { if cluster == nil {
return http.StatusInternalServerError, nil, nil return http.StatusInternalServerError, nil, fmt.Errorf("failed to fetch cluster details")
} }
clusterName = cluster.Name clusterName = cluster.Name
clusterID = cluster.ID clusterID = cluster.ID

View File

@ -155,14 +155,12 @@ func handleSysSealStatusRaw(core *vault.Core, w http.ResponseWriter, r *http.Req
var clusterName, clusterID string var clusterName, clusterID string
if !sealed { if !sealed {
cluster, err := core.Cluster() cluster, err := core.Cluster()
// Don't set the cluster details in the status when Vault is sealed
if err != nil { if err != nil {
respondError(w, http.StatusInternalServerError, err) respondError(w, http.StatusInternalServerError, err)
return return
} }
if cluster == nil { if cluster == nil {
respondError(w, http.StatusInternalServerError, nil) respondError(w, http.StatusInternalServerError, fmt.Errorf("failed to fetch cluster details"))
return return
} }
clusterName = cluster.Name clusterName = cluster.Name

View File

@ -25,17 +25,18 @@ type Cluster struct {
// Cluster fetches the details of either local or global cluster based on the // Cluster fetches the details of either local or global cluster based on the
// input. This method errors out when Vault is sealed. // input. This method errors out when Vault is sealed.
func (c *Core) Cluster() (*Cluster, error) { func (c *Core) Cluster() (*Cluster, error) {
var cluster Cluster
// Fetch the storage entry. This call fails when Vault is sealed. // Fetch the storage entry. This call fails when Vault is sealed.
entry, err := c.barrier.Get(coreLocalClusterInfoPath) entry, err := c.barrier.Get(coreLocalClusterInfoPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if entry == nil { if entry == nil {
return nil, nil return &cluster, nil
} }
// Decode the cluster information // Decode the cluster information
var cluster Cluster
if err = jsonutil.DecodeJSON(entry.Value, &cluster); err != nil { if err = jsonutil.DecodeJSON(entry.Value, &cluster); err != nil {
return nil, fmt.Errorf("failed to decode cluster details: %v", err) return nil, fmt.Errorf("failed to decode cluster details: %v", err)
} }
@ -58,42 +59,60 @@ func (c *Core) setupCluster() error {
c.logger.Printf("[ERR] core: failed to get cluster details: %v", err) c.logger.Printf("[ERR] core: failed to get cluster details: %v", err)
return err return err
} }
if cluster != nil {
// If index is already present, don't update it if cluster == nil {
return nil cluster = &Cluster{}
} }
// If cluster name is not supplied, generate one var modified bool
if c.clusterName == "" {
clusterNameBytes, err := uuid.GenerateRandomBytes(4) 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 { if err != nil {
c.logger.Printf("[ERR] core: failed to generate cluster name: %v", err) c.logger.Printf("[ERR] core: failed to generate cluster identifier: %v", err)
return err return err
} }
c.clusterName = fmt.Sprintf("vault-cluster-%08x", clusterNameBytes) cluster.ID = clusterID
c.logger.Printf("[DEBUG] core: cluster ID set to %s", cluster.ID)
modified = true
} }
// Generate a clusterID if modified {
clusterID, err := uuid.GenerateUUID() // Encode the cluster information into as a JSON string
if err != nil { rawCluster, err := json.Marshal(cluster)
c.logger.Printf("[ERR] core: failed to generate cluster identifier: %v", err) if err != nil {
return err 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
}
} }
// Encode the cluster information into as a JSON string return nil
rawCluster, err := json.Marshal(&Cluster{
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: coreLocalClusterInfoPath,
Value: rawCluster,
})
} }