From 2bdeaa0c6ad7d981ae8b66f3af43f1e4a50ae97a Mon Sep 17 00:00:00 2001 From: Ryan Uber Date: Wed, 24 Sep 2014 18:30:34 -0700 Subject: [PATCH] consul: restructuring --- command/agent/keyring.go | 12 +- command/agent/rpc.go | 29 ++-- consul/internal_endpoint.go | 261 ++++++++++++++---------------------- consul/structs/structs.go | 16 ++- 4 files changed, 134 insertions(+), 184 deletions(-) diff --git a/command/agent/keyring.go b/command/agent/keyring.go index e816c3d784..827aa76bc7 100644 --- a/command/agent/keyring.go +++ b/command/agent/keyring.go @@ -66,9 +66,9 @@ func loadKeyringFile(c *serf.Config) error { // performing various operations on the encryption keyring. func (a *Agent) keyringProcess( method string, - args *structs.KeyringRequest) (*structs.KeyringResponse, error) { + args *structs.KeyringRequest) (*structs.KeyringResponses, error) { - var reply structs.KeyringResponse + var reply structs.KeyringResponses if a.server == nil { return nil, fmt.Errorf("keyring operations must run against a server node") } @@ -81,28 +81,28 @@ func (a *Agent) keyringProcess( // ListKeys lists out all keys installed on the collective Consul cluster. This // includes both servers and clients in all DC's. -func (a *Agent) ListKeys() (*structs.KeyringResponse, error) { +func (a *Agent) ListKeys() (*structs.KeyringResponses, error) { args := structs.KeyringRequest{} args.AllowStale = true return a.keyringProcess("Internal.ListKeys", &args) } // InstallKey installs a new gossip encryption key -func (a *Agent) InstallKey(key string) (*structs.KeyringResponse, error) { +func (a *Agent) InstallKey(key string) (*structs.KeyringResponses, error) { args := structs.KeyringRequest{Key: key} args.AllowStale = true return a.keyringProcess("Internal.InstallKey", &args) } // UseKey changes the primary encryption key used to encrypt messages -func (a *Agent) UseKey(key string) (*structs.KeyringResponse, error) { +func (a *Agent) UseKey(key string) (*structs.KeyringResponses, error) { args := structs.KeyringRequest{Key: key} args.AllowStale = true return a.keyringProcess("Internal.UseKey", &args) } // RemoveKey will remove a gossip encryption key from the keyring -func (a *Agent) RemoveKey(key string) (*structs.KeyringResponse, error) { +func (a *Agent) RemoveKey(key string) (*structs.KeyringResponses, error) { args := structs.KeyringRequest{Key: key} args.AllowStale = true return a.keyringProcess("Internal.RemoveKey", &args) diff --git a/command/agent/rpc.go b/command/agent/rpc.go index 983cc3481c..5d6c5c8a7c 100644 --- a/command/agent/rpc.go +++ b/command/agent/rpc.go @@ -606,7 +606,7 @@ func (i *AgentRPC) handleReload(client *rpcClient, seq uint64) error { func (i *AgentRPC) handleKeyring(client *rpcClient, seq uint64, cmd string) error { var req keyRequest - var queryResp *structs.KeyringResponse + var queryResp *structs.KeyringResponses var resp keyResponse var err error @@ -636,14 +636,27 @@ func (i *AgentRPC) handleKeyring(client *rpcClient, seq uint64, cmd string) erro Error: errToString(err), } - if queryResp != nil { - resp = keyResponse{ - Messages: queryResp.Messages, - Keys: queryResp.Keys, - NumNodes: queryResp.NumNodes, - NumResp: queryResp.NumResp, - NumErr: queryResp.NumErr, + if resp.Messages == nil { + resp.Messages = make(map[string]string) + } + if resp.Keys == nil { + resp.Keys = make(map[string]int) + } + + for _, kr := range queryResp.Responses { + for node, msg := range kr.Messages { + resp.Messages[node+"."+kr.Datacenter] = msg } + for key, qty := range kr.Keys { + if _, ok := resp.Keys[key]; ok { + resp.Keys[key] += qty + } else { + resp.Keys[key] = qty + } + } + resp.NumNodes += kr.NumNodes + resp.NumResp += kr.NumResp + resp.NumErr += kr.NumErr } return client.Send(&header, resp) diff --git a/consul/internal_endpoint.go b/consul/internal_endpoint.go index 7cc6487478..e7dafb319f 100644 --- a/consul/internal_endpoint.go +++ b/consul/internal_endpoint.go @@ -1,10 +1,7 @@ package consul import ( - "fmt" - "github.com/hashicorp/consul/consul/structs" - "github.com/hashicorp/serf/serf" ) // Internal endpoint is used to query the miscellaneous info that @@ -66,49 +63,69 @@ func (m *Internal) EventFire(args *structs.EventFireRequest, return m.srv.UserEvent(args.Name, args.Payload) } -// TODO(ryanuber): Clean up all of these methods -func (m *Internal) InstallKey(args *structs.KeyringRequest, - reply *structs.KeyringResponse) error { +func (m *Internal) ListKeys( + args *structs.KeyringRequest, + reply *structs.KeyringResponses) error { - var respLAN, respWAN *serf.KeyResponse - var err error - - if reply.Messages == nil { - reply.Messages = make(map[string]string) - } - if reply.Keys == nil { - reply.Keys = make(map[string]int) - } - - m.srv.setQueryMeta(&reply.QueryMeta) - - // Do a LAN key install. This will be invoked in each DC once the RPC call - // is forwarded below. - respLAN, err = m.srv.KeyManagerLAN().InstallKey(args.Key) - for node, msg := range respLAN.Messages { - reply.Messages["client."+node+"."+m.srv.config.Datacenter] = msg - } - reply.NumResp += respLAN.NumResp - reply.NumErr += respLAN.NumErr - reply.NumNodes += respLAN.NumNodes + respLAN, err := m.srv.KeyManagerLAN().ListKeys() if err != nil { - return fmt.Errorf("failed rotating LAN keyring in %s: %s", - m.srv.config.Datacenter, - err) + return err } + reply.Responses = append(reply.Responses, &structs.KeyringResponse{ + Datacenter: m.srv.config.Datacenter, + Messages: respLAN.Messages, + Keys: respLAN.Keys, + NumResp: respLAN.NumResp, + NumNodes: respLAN.NumNodes, + NumErr: respLAN.NumErr, + }) if !args.Forwarded { - // Only perform WAN key rotation once. - respWAN, err = m.srv.KeyManagerWAN().InstallKey(args.Key) + respWAN, err := m.srv.KeyManagerWAN().ListKeys() if err != nil { return err } - for node, msg := range respWAN.Messages { - reply.Messages["server."+node] = msg - } - reply.NumResp += respWAN.NumResp - reply.NumErr += respWAN.NumErr - reply.NumNodes += respWAN.NumNodes + reply.Responses = append(reply.Responses, &structs.KeyringResponse{ + Datacenter: m.srv.config.Datacenter, + Messages: respWAN.Messages, + Keys: respWAN.Keys, + NumResp: respWAN.NumResp, + NumNodes: respWAN.NumNodes, + NumErr: respWAN.NumErr, + }) + + // Mark key rotation as being already forwarded, then forward. + args.Forwarded = true + return m.srv.forwardAll("Internal.ListKeys", args, reply) + } + + return nil +} + +func (m *Internal) InstallKey( + args *structs.KeyringRequest, + reply *structs.KeyringResponses) error { + + respLAN, _ := m.srv.KeyManagerLAN().InstallKey(args.Key) + reply.Responses = append(reply.Responses, &structs.KeyringResponse{ + Datacenter: m.srv.config.Datacenter, + Messages: respLAN.Messages, + Keys: respLAN.Keys, + NumResp: respLAN.NumResp, + NumNodes: respLAN.NumNodes, + NumErr: respLAN.NumErr, + }) + + if !args.Forwarded { + respWAN, _ := m.srv.KeyManagerWAN().InstallKey(args.Key) + reply.Responses = append(reply.Responses, &structs.KeyringResponse{ + Datacenter: m.srv.config.Datacenter, + Messages: respWAN.Messages, + Keys: respWAN.Keys, + NumResp: respWAN.NumResp, + NumNodes: respWAN.NumNodes, + NumErr: respWAN.NumErr, + }) // Mark key rotation as being already forwarded, then forward. args.Forwarded = true @@ -118,47 +135,30 @@ func (m *Internal) InstallKey(args *structs.KeyringRequest, return nil } -func (m *Internal) UseKey(args *structs.KeyringRequest, - reply *structs.KeyringResponse) error { - var respLAN, respWAN *serf.KeyResponse - var err error +func (m *Internal) UseKey( + args *structs.KeyringRequest, + reply *structs.KeyringResponses) error { - if reply.Messages == nil { - reply.Messages = make(map[string]string) - } - if reply.Keys == nil { - reply.Keys = make(map[string]int) - } - - m.srv.setQueryMeta(&reply.QueryMeta) - - // Do a LAN key install. This will be invoked in each DC once the RPC call - // is forwarded below. - respLAN, err = m.srv.KeyManagerLAN().UseKey(args.Key) - for node, msg := range respLAN.Messages { - reply.Messages["client."+node+"."+m.srv.config.Datacenter] = msg - } - reply.NumResp += respLAN.NumResp - reply.NumErr += respLAN.NumErr - reply.NumNodes += respLAN.NumNodes - if err != nil { - return fmt.Errorf("failed rotating LAN keyring in %s: %s", - m.srv.config.Datacenter, - err) - } + respLAN, _ := m.srv.KeyManagerLAN().UseKey(args.Key) + reply.Responses = append(reply.Responses, &structs.KeyringResponse{ + Datacenter: m.srv.config.Datacenter, + Messages: respLAN.Messages, + Keys: respLAN.Keys, + NumResp: respLAN.NumResp, + NumNodes: respLAN.NumNodes, + NumErr: respLAN.NumErr, + }) if !args.Forwarded { - // Only perform WAN key rotation once. - respWAN, err = m.srv.KeyManagerWAN().UseKey(args.Key) - if err != nil { - return err - } - for node, msg := range respWAN.Messages { - reply.Messages["server."+node] = msg - } - reply.NumResp += respWAN.NumResp - reply.NumErr += respWAN.NumErr - reply.NumNodes += respWAN.NumNodes + respWAN, _ := m.srv.KeyManagerWAN().UseKey(args.Key) + reply.Responses = append(reply.Responses, &structs.KeyringResponse{ + Datacenter: m.srv.config.Datacenter, + Messages: respWAN.Messages, + Keys: respWAN.Keys, + NumResp: respWAN.NumResp, + NumNodes: respWAN.NumNodes, + NumErr: respWAN.NumErr, + }) // Mark key rotation as being already forwarded, then forward. args.Forwarded = true @@ -168,47 +168,30 @@ func (m *Internal) UseKey(args *structs.KeyringRequest, return nil } -func (m *Internal) RemoveKey(args *structs.KeyringRequest, - reply *structs.KeyringResponse) error { - var respLAN, respWAN *serf.KeyResponse - var err error +func (m *Internal) RemoveKey( + args *structs.KeyringRequest, + reply *structs.KeyringResponses) error { - if reply.Messages == nil { - reply.Messages = make(map[string]string) - } - if reply.Keys == nil { - reply.Keys = make(map[string]int) - } - - m.srv.setQueryMeta(&reply.QueryMeta) - - // Do a LAN key install. This will be invoked in each DC once the RPC call - // is forwarded below. - respLAN, err = m.srv.KeyManagerLAN().RemoveKey(args.Key) - for node, msg := range respLAN.Messages { - reply.Messages["client."+node+"."+m.srv.config.Datacenter] = msg - } - reply.NumResp += respLAN.NumResp - reply.NumErr += respLAN.NumErr - reply.NumNodes += respLAN.NumNodes - if err != nil { - return fmt.Errorf("failed rotating LAN keyring in %s: %s", - m.srv.config.Datacenter, - err) - } + respLAN, _ := m.srv.KeyManagerLAN().RemoveKey(args.Key) + reply.Responses = append(reply.Responses, &structs.KeyringResponse{ + Datacenter: m.srv.config.Datacenter, + Messages: respLAN.Messages, + Keys: respLAN.Keys, + NumResp: respLAN.NumResp, + NumNodes: respLAN.NumNodes, + NumErr: respLAN.NumErr, + }) if !args.Forwarded { - // Only perform WAN key rotation once. - respWAN, err = m.srv.KeyManagerWAN().RemoveKey(args.Key) - if err != nil { - return err - } - for node, msg := range respWAN.Messages { - reply.Messages["server."+node] = msg - } - reply.NumResp += respWAN.NumResp - reply.NumErr += respWAN.NumErr - reply.NumNodes += respWAN.NumNodes + respWAN, _ := m.srv.KeyManagerWAN().RemoveKey(args.Key) + reply.Responses = append(reply.Responses, &structs.KeyringResponse{ + Datacenter: m.srv.config.Datacenter, + Messages: respWAN.Messages, + Keys: respWAN.Keys, + NumResp: respWAN.NumResp, + NumNodes: respWAN.NumNodes, + NumErr: respWAN.NumErr, + }) // Mark key rotation as being already forwarded, then forward. args.Forwarded = true @@ -217,53 +200,3 @@ func (m *Internal) RemoveKey(args *structs.KeyringRequest, return nil } - -func (m *Internal) ListKeys(args *structs.KeyringRequest, - reply *structs.KeyringResponse) error { - var respLAN, respWAN *serf.KeyResponse - var err error - - if reply.Messages == nil { - reply.Messages = make(map[string]string) - } - if reply.Keys == nil { - reply.Keys = make(map[string]int) - } - - m.srv.setQueryMeta(&reply.QueryMeta) - - // Do a LAN key install. This will be invoked in each DC once the RPC call - // is forwarded below. - respLAN, err = m.srv.KeyManagerLAN().ListKeys() - for node, msg := range respLAN.Messages { - reply.Messages["client."+node+"."+m.srv.config.Datacenter] = msg - } - reply.NumResp += respLAN.NumResp - reply.NumErr += respLAN.NumErr - reply.NumNodes += respLAN.NumNodes - if err != nil { - return fmt.Errorf("failed rotating LAN keyring in %s: %s", - m.srv.config.Datacenter, - err) - } - - if !args.Forwarded { - // Only perform WAN key rotation once. - respWAN, err = m.srv.KeyManagerWAN().ListKeys() - if err != nil { - return err - } - for node, msg := range respWAN.Messages { - reply.Messages["server."+node] = msg - } - reply.NumResp += respWAN.NumResp - reply.NumErr += respWAN.NumErr - reply.NumNodes += respWAN.NumNodes - - // Mark key rotation as being already forwarded, then forward. - args.Forwarded = true - return m.srv.forwardAll("Internal.ListKeys", args, reply) - } - - return nil -} diff --git a/consul/structs/structs.go b/consul/structs/structs.go index 31a6e319f3..3f029ee812 100644 --- a/consul/structs/structs.go +++ b/consul/structs/structs.go @@ -543,10 +543,14 @@ type KeyringRequest struct { // KeyringResponse is a unified key response and can be used for install, // remove, use, as well as listing key queries. type KeyringResponse struct { - Messages map[string]string - Keys map[string]int - NumNodes int - NumResp int - NumErr int - QueryMeta + Datacenter string + Messages map[string]string + Keys map[string]int + NumNodes int + NumResp int + NumErr int +} + +type KeyringResponses struct { + Responses []*KeyringResponse }