github.com/bigcommerce/nomad@v0.9.3-bc/client/fingerprint/vault.go (about)

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