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 }