github.com/anuvu/nomad@v0.8.7-atom1/command/agent/keyring.go (about) 1 package agent 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 11 "github.com/hashicorp/memberlist" 12 "github.com/hashicorp/serf/serf" 13 ) 14 15 const ( 16 serfKeyring = "server/serf.keyring" 17 ) 18 19 // initKeyring will create a keyring file at a given path. 20 func initKeyring(path, key string) error { 21 var keys []string 22 23 if keyBytes, err := base64.StdEncoding.DecodeString(key); err != nil { 24 return fmt.Errorf("Invalid key: %s", err) 25 } else if err := memberlist.ValidateKey(keyBytes); err != nil { 26 return fmt.Errorf("Invalid key: %s", err) 27 } 28 29 // Just exit if the file already exists. 30 if _, err := os.Stat(path); err == nil { 31 return nil 32 } 33 34 keys = append(keys, key) 35 keyringBytes, err := json.Marshal(keys) 36 if err != nil { 37 return err 38 } 39 40 if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil { 41 return err 42 } 43 44 fh, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600) 45 if err != nil { 46 return err 47 } 48 defer fh.Close() 49 50 if _, err := fh.Write(keyringBytes); err != nil { 51 os.Remove(path) 52 return err 53 } 54 55 return nil 56 } 57 58 // loadKeyringFile will load a gossip encryption keyring out of a file. The file 59 // must be in JSON format and contain a list of encryption key strings. 60 func loadKeyringFile(c *serf.Config) error { 61 if c.KeyringFile == "" { 62 return nil 63 } 64 65 if _, err := os.Stat(c.KeyringFile); err != nil { 66 return err 67 } 68 69 // Read in the keyring file data 70 keyringData, err := ioutil.ReadFile(c.KeyringFile) 71 if err != nil { 72 return err 73 } 74 75 // Decode keyring JSON 76 keys := make([]string, 0) 77 if err := json.Unmarshal(keyringData, &keys); err != nil { 78 return err 79 } 80 81 // Decode base64 values 82 keysDecoded := make([][]byte, len(keys)) 83 for i, key := range keys { 84 keyBytes, err := base64.StdEncoding.DecodeString(key) 85 if err != nil { 86 return err 87 } 88 keysDecoded[i] = keyBytes 89 } 90 91 // Guard against empty keyring 92 if len(keysDecoded) == 0 { 93 return fmt.Errorf("no keys present in keyring file: %s", c.KeyringFile) 94 } 95 96 // Create the keyring 97 keyring, err := memberlist.NewKeyring(keysDecoded, keysDecoded[0]) 98 if err != nil { 99 return err 100 } 101 102 c.MemberlistConfig.Keyring = keyring 103 104 // Success! 105 return nil 106 }