github.com/hhrutter/nomad@v0.6.0-rc2.0.20170723054333-80c4b03f0705/client/fingerprint/vault.go (about) 1 package fingerprint 2 3 import ( 4 "fmt" 5 "log" 6 "strconv" 7 "strings" 8 "time" 9 10 client "github.com/hashicorp/nomad/client/config" 11 "github.com/hashicorp/nomad/nomad/structs" 12 vapi "github.com/hashicorp/vault/api" 13 ) 14 15 const ( 16 vaultAvailable = "available" 17 vaultUnavailable = "unavailable" 18 ) 19 20 // VaultFingerprint is used to fingerprint for Vault 21 type VaultFingerprint struct { 22 logger *log.Logger 23 client *vapi.Client 24 lastState string 25 } 26 27 // NewVaultFingerprint is used to create a Vault fingerprint 28 func NewVaultFingerprint(logger *log.Logger) Fingerprint { 29 return &VaultFingerprint{logger: logger, lastState: vaultUnavailable} 30 } 31 32 func (f *VaultFingerprint) Fingerprint(config *client.Config, node *structs.Node) (bool, error) { 33 if config.VaultConfig == nil || !config.VaultConfig.IsEnabled() { 34 return false, 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 false, 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 false, 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 // Clear any attributes set by a previous fingerprint. 55 f.clearVaultAttributes(node) 56 57 // Print a message indicating that Vault is not available anymore 58 if f.lastState == vaultAvailable { 59 f.logger.Printf("[INFO] fingerprint.vault: Vault is unavailable") 60 } 61 f.lastState = vaultUnavailable 62 return false, nil 63 } 64 65 node.Attributes["vault.accessible"] = strconv.FormatBool(true) 66 // We strip the Vault prefix becasue < 0.6.2 the version looks like: 67 // status.Version = "Vault v0.6.1" 68 node.Attributes["vault.version"] = strings.TrimPrefix(status.Version, "Vault ") 69 node.Attributes["vault.cluster_id"] = status.ClusterID 70 node.Attributes["vault.cluster_name"] = status.ClusterName 71 72 // If Vault was previously unavailable print a message to indicate the Agent 73 // is available now 74 if f.lastState == vaultUnavailable { 75 f.logger.Printf("[INFO] fingerprint.vault: Vault is available") 76 } 77 f.lastState = vaultAvailable 78 return true, nil 79 } 80 81 func (f *VaultFingerprint) clearVaultAttributes(n *structs.Node) { 82 delete(n.Attributes, "vault.accessible") 83 delete(n.Attributes, "vault.version") 84 delete(n.Attributes, "vault.cluster_id") 85 delete(n.Attributes, "vault.cluster_name") 86 } 87 88 func (f *VaultFingerprint) Periodic() (bool, time.Duration) { 89 return true, 15 * time.Second 90 }