From 7b6f3d6dcc23e8df1f91e0979d4ef65cec92a3c8 Mon Sep 17 00:00:00 2001 From: Ryan Uber Date: Mon, 8 Sep 2014 23:25:38 -0700 Subject: [PATCH] agent: install key command implemented --- command/agent/agent.go | 21 +++++++++++++++- command/agent/rpc.go | 50 ++++++++++++++++++++++++++----------- command/agent/rpc_client.go | 26 +++++++++++++++++++ command/keys.go | 40 +++++++++++++++++++++++------ 4 files changed, 113 insertions(+), 24 deletions(-) diff --git a/command/agent/agent.go b/command/agent/agent.go index b219f18bc7..f1d52075f2 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -756,5 +756,24 @@ func (a *Agent) ListKeysWAN() (*serf.KeyResponse, error) { km := a.server.KeyManagerWAN() return km.ListKeys() } - return nil, nil + return nil, fmt.Errorf("WAN keyring not available on client node") +} + +// InstallKeyWAN installs a new WAN gossip encryption key on server nodes +func (a *Agent) InstallKeyWAN(key string) (*serf.KeyResponse, error) { + if a.server != nil { + km := a.server.KeyManagerWAN() + return km.InstallKey(key) + } + return nil, fmt.Errorf("WAN keyring not available on client node") +} + +// InstallKeyLAN installs a new LAN gossip encryption key on all nodes +func (a *Agent) InstallKeyLAN(key string) (*serf.KeyResponse, error) { + if a.server != nil { + km := a.server.KeyManagerLAN() + return km.InstallKey(key) + } + km := a.client.KeyManagerLAN() + return km.InstallKey(key) } diff --git a/command/agent/rpc.go b/command/agent/rpc.go index 7030f6538d..5124a6d659 100644 --- a/command/agent/rpc.go +++ b/command/agent/rpc.go @@ -111,6 +111,10 @@ type joinResponse struct { Num int32 } +type keyRequest struct { + Key string +} + type keyResponse struct { Messages map[string]string NumNodes int @@ -389,19 +393,13 @@ func (i *AgentRPC) handleRequest(client *rpcClient, reqHeader *requestHeader) er case reloadCommand: return i.handleReload(client, seq) - case listKeysLANCommand: - return i.handleListKeysLAN(client, seq) + case listKeysLANCommand, listKeysWANCommand: + return i.handleListKeys(client, seq, command) - case listKeysWANCommand: - return i.handleListKeysWAN(client, seq) + case installKeyLANCommand, installKeyWANCommand: + return i.handleInstallKey(client, seq, command) /* - case installKeyLANCommand: - return i.handleInstallKeyLAN(client, seq) - - case installKeyWANCommand: - return i.handleInstallKeyWAN(client, seq) - case useKeyLANCommand: return i.handleUseKeyLAN(client, seq) @@ -625,8 +623,16 @@ func (i *AgentRPC) handleReload(client *rpcClient, seq uint64) error { return client.Send(&resp, nil) } -func (i *AgentRPC) handleListKeysLAN(client *rpcClient, seq uint64) error { - queryResp, err := i.agent.ListKeysLAN() +func (i *AgentRPC) handleListKeys(client *rpcClient, seq uint64, cmd string) error { + var queryResp *serf.KeyResponse + var err error + + switch cmd { + case listKeysWANCommand: + queryResp, err = i.agent.ListKeysWAN() + default: + queryResp, err = i.agent.ListKeysLAN() + } header := responseHeader{ Seq: seq, @@ -644,15 +650,29 @@ func (i *AgentRPC) handleListKeysLAN(client *rpcClient, seq uint64) error { return client.Send(&header, &resp) } -func (i *AgentRPC) handleListKeysWAN(client *rpcClient, seq uint64) error { - queryResp, err := i.agent.ListKeysWAN() +func (i *AgentRPC) handleInstallKey(client *rpcClient, seq uint64, cmd string) error { + var req keyRequest + var resp keyResponse + var queryResp *serf.KeyResponse + var err error + + if err = client.dec.Decode(&req); err != nil { + return fmt.Errorf("decode failed: %v", err) + } + + switch cmd { + case installKeyWANCommand: + queryResp, err = i.agent.InstallKeyWAN(req.Key) + default: + queryResp, err = i.agent.InstallKeyLAN(req.Key) + } header := responseHeader{ Seq: seq, Error: errToString(err), } - resp := keyResponse{ + resp = keyResponse{ Messages: queryResp.Messages, Keys: queryResp.Keys, NumResp: queryResp.NumResp, diff --git a/command/agent/rpc_client.go b/command/agent/rpc_client.go index daa72e1c05..c6b442f773 100644 --- a/command/agent/rpc_client.go +++ b/command/agent/rpc_client.go @@ -198,6 +198,32 @@ func (c *RPCClient) ListKeysWAN() (map[string]int, int, map[string]string, error return resp.Keys, resp.NumNodes, resp.Messages, err } +func (c *RPCClient) InstallKeyWAN(key string) (map[string]string, error) { + header := requestHeader{ + Command: installKeyWANCommand, + Seq: c.getSeq(), + } + + req := keyRequest{key} + + resp := new(keyResponse) + err := c.genericRPC(&header, &req, resp) + return resp.Messages, err +} + +func (c *RPCClient) InstallKeyLAN(key string) (map[string]string, error) { + header := requestHeader{ + Command: installKeyLANCommand, + Seq: c.getSeq(), + } + + req := keyRequest{key} + + resp := new(keyResponse) + err := c.genericRPC(&header, &req, resp) + return resp.Messages, err +} + // Leave is used to trigger a graceful leave and shutdown func (c *RPCClient) Leave() error { header := requestHeader{ diff --git a/command/keys.go b/command/keys.go index 9be460063c..2c0ce8f8ec 100644 --- a/command/keys.go +++ b/command/keys.go @@ -40,6 +40,10 @@ func (c *KeysCommand) Run(args []string) int { Ui: c.Ui, } + var out []string + var failures map[string]string + var err error + // Only accept a single argument found := listKeys for _, arg := range []string{installKey, useKey, removeKey} { @@ -68,21 +72,20 @@ func (c *KeysCommand) Run(args []string) int { var keys map[string]int var numNodes int - var messages map[string]string - var err error - var out []string if wan { - keys, numNodes, messages, err = client.ListKeysWAN() + keys, numNodes, failures, err = client.ListKeysWAN() } else { - keys, numNodes, messages, err = client.ListKeysLAN() + keys, numNodes, failures, err = client.ListKeysLAN() } if err != nil { - for node, msg := range messages { - out = append(out, fmt.Sprintf("failed: %s | %s", node, msg)) + if len(failures) > 0 { + for node, msg := range failures { + out = append(out, fmt.Sprintf("failed: %s | %s", node, msg)) + } + c.Ui.Error(columnize.SimpleFormat(out)) } - c.Ui.Error(columnize.SimpleFormat(out)) c.Ui.Error("") c.Ui.Error(fmt.Sprintf("Failed gathering member keys: %s", err)) return 1 @@ -100,6 +103,27 @@ func (c *KeysCommand) Run(args []string) int { } if installKey != "" { + if wan { + c.Ui.Info("Installing new WAN gossip encryption key...") + failures, err = client.InstallKeyWAN(installKey) + } else { + c.Ui.Info("Installing new LAN gossip encryption key...") + failures, err = client.InstallKeyLAN(installKey) + } + + if err != nil { + if len(failures) > 0 { + for node, msg := range failures { + out = append(out, fmt.Sprintf("failed: %s | %s", node, msg)) + } + c.Ui.Error(columnize.SimpleFormat(out)) + } + c.Ui.Error("") + c.Ui.Error(fmt.Sprintf("Error installing key: %s", err)) + return 1 + } + + c.Ui.Info("Successfully installed key!") return 0 }