-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkeyring.go
118 lines (101 loc) · 3.35 KB
/
keyring.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package serfer
import (
"encoding/base64"
"fmt"
"github.com/hashicorp/memberlist"
"github.com/hashicorp/serf/serf"
)
// KeyResponse is an alias for serf.KeyResponse
type KeyResponse = serf.KeyResponse
// Keyring set a list of keys to be used to decode communication between nodes
func (s *Serfer) Keyring(keys ...string) error {
if len(keys) == 0 {
return fmt.Errorf("Keyring should contain at least one key")
}
kr, err := keyring(keys...)
if err != nil {
return err
}
// But if there is a SecretKey, add it to the Keyring (if isn't there already)
if len(s.Conf.MemberlistConfig.SecretKey) != 0 {
// AddKey don't add an existing key. They won't be repeated
kr.AddKey(s.Conf.MemberlistConfig.SecretKey)
kr.UseKey(s.Conf.MemberlistConfig.SecretKey)
} else {
s.Conf.MemberlistConfig.SecretKey = kr.GetPrimaryKey()
}
s.Conf.MemberlistConfig.Keyring = kr
return nil
}
func keyring(keys ...string) (*memberlist.Keyring, error) {
if len(keys) == 0 {
return nil, fmt.Errorf("keyring should contain at least one key")
}
decodedKeys := make([][]byte, len(keys))
for i, k := range keys {
decodedKey, err := base64.StdEncoding.DecodeString(k)
if err != nil {
return nil, fmt.Errorf("can't decode key number %d. %s", i, err)
}
if l := len(decodedKey); l != 16 && l != 24 && l != 32 {
return nil, fmt.Errorf("incorrect size of key number %d, the size is %d and should be 16, 24 or 32 bytes", i, l)
}
decodedKeys[i] = decodedKey
}
return memberlist.NewKeyring(decodedKeys, decodedKeys[0])
}
// GetKeys return all the keys used by the cluster.
func (s *Serfer) GetKeys() [][]byte {
// if s.Conf.MemberlistConfig.EncryptionEnabled()
if len(s.Conf.MemberlistConfig.SecretKey) != 0 {
keys := make([][]byte, 1)
keys[0] = s.Conf.MemberlistConfig.SecretKey
return keys
}
return s.Conf.MemberlistConfig.Keyring.GetKeys()
}
func emptyKeyResponse() *KeyResponse {
return &KeyResponse{
NumNodes: 1,
NumResp: 1,
NumErr: 0,
}
}
// InstallKey send a query to install a new key on all the members. If the
// cluster does not exists (not join to a cluster yet), will add the key
func (s *Serfer) InstallKey(key string) (*KeyResponse, error) {
if s.cluster != nil {
manager := s.cluster.KeyManager()
return manager.InstallKey(key)
}
return emptyKeyResponse(), s.Conf.MemberlistConfig.Keyring.AddKey([]byte(key))
}
// UseKey sends a query to all members to switch to the given primary key. If
// the cluster does not exists will switch to the given primary key
func (s *Serfer) UseKey(key string) (*KeyResponse, error) {
if s.cluster != nil {
manager := s.cluster.KeyManager()
return manager.UseKey(key)
}
return emptyKeyResponse(), s.Conf.MemberlistConfig.Keyring.UseKey([]byte(key))
}
// RemoveKey sends a query to all members to remove a key from the keyring
func (s *Serfer) RemoveKey(key string) (*KeyResponse, error) {
if s.cluster != nil {
manager := s.cluster.KeyManager()
return manager.RemoveKey(key)
}
return emptyKeyResponse(), s.Conf.MemberlistConfig.Keyring.RemoveKey([]byte(key))
}
// ListKeys sends a query to all members to return a list of their keys
func (s *Serfer) ListKeys() (*KeyResponse, error) {
if s.cluster != nil {
manager := s.cluster.KeyManager()
return manager.ListKeys()
}
resp := emptyKeyResponse()
for _, k := range s.Conf.MemberlistConfig.Keyring.GetKeys() {
resp.Keys[string(k)] = 1
}
return resp, nil
}