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 }