github.com/anuvu/nomad@v0.8.7-atom1/client/fingerprint/vault.go (about)

     1  package fingerprint
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strconv"
     7  	"strings"
     8  	"time"
     9  
    10  	cstructs "github.com/hashicorp/nomad/client/structs"
    11  	vapi "github.com/hashicorp/vault/api"
    12  )
    13  
    14  const (
    15  	vaultAvailable   = "available"
    16  	vaultUnavailable = "unavailable"
    17  )
    18  
    19  // VaultFingerprint is used to fingerprint for Vault
    20  type VaultFingerprint struct {
    21  	logger    *log.Logger
    22  	client    *vapi.Client
    23  	lastState string
    24  }
    25  
    26  // NewVaultFingerprint is used to create a Vault fingerprint
    27  func NewVaultFingerprint(logger *log.Logger) Fingerprint {
    28  	return &VaultFingerprint{logger: logger, lastState: vaultUnavailable}
    29  }
    30  
    31  func (f *VaultFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error {
    32  	config := req.Config
    33  
    34  	if config.VaultConfig == nil || !config.VaultConfig.IsEnabled() {
    35  		return nil
    36  	}
    37  
    38  	// Only create the client once to avoid creating too many connections to
    39  	// Vault.
    40  	if f.client == nil {
    41  		vaultConfig, err := config.VaultConfig.ApiConfig()
    42  		if err != nil {
    43  			return fmt.Errorf("Failed to initialize the Vault client config: %v", err)
    44  		}
    45  
    46  		f.client, err = vapi.NewClient(vaultConfig)
    47  		if err != nil {
    48  			return fmt.Errorf("Failed to initialize Vault client: %s", err)
    49  		}
    50  	}
    51  
    52  	// Connect to vault and parse its information
    53  	status, err := f.client.Sys().SealStatus()
    54  	if err != nil {
    55  		f.clearVaultAttributes(resp)
    56  		// Print a message indicating that Vault is not available anymore
    57  		if f.lastState == vaultAvailable {
    58  			f.logger.Printf("[INFO] fingerprint.vault: Vault is unavailable")
    59  		}
    60  		f.lastState = vaultUnavailable
    61  		return nil
    62  	}
    63  
    64  	resp.AddAttribute("vault.accessible", strconv.FormatBool(true))
    65  	// We strip the Vault prefix because < 0.6.2 the version looks like:
    66  	// status.Version = "Vault v0.6.1"
    67  	resp.AddAttribute("vault.version", strings.TrimPrefix(status.Version, "Vault "))
    68  	resp.AddAttribute("vault.cluster_id", status.ClusterID)
    69  	resp.AddAttribute("vault.cluster_name", status.ClusterName)
    70  
    71  	// If Vault was previously unavailable print a message to indicate the Agent
    72  	// is available now
    73  	if f.lastState == vaultUnavailable {
    74  		f.logger.Printf("[INFO] fingerprint.vault: Vault is available")
    75  	}
    76  	f.lastState = vaultAvailable
    77  	resp.Detected = true
    78  	return nil
    79  }
    80  
    81  func (f *VaultFingerprint) Periodic() (bool, time.Duration) {
    82  	return true, 15 * time.Second
    83  }
    84  
    85  func (f *VaultFingerprint) clearVaultAttributes(r *cstructs.FingerprintResponse) {
    86  	r.RemoveAttribute("vault.accessible")
    87  	r.RemoveAttribute("vault.version")
    88  	r.RemoveAttribute("vault.cluster_id")
    89  	r.RemoveAttribute("vault.cluster_name")
    90  }