consul: restructuring

pull/336/head
Ryan Uber 2014-09-24 18:30:34 -07:00
parent 8dec2744da
commit 2bdeaa0c6a
4 changed files with 134 additions and 184 deletions

View File

@ -66,9 +66,9 @@ func loadKeyringFile(c *serf.Config) error {
// performing various operations on the encryption keyring. // performing various operations on the encryption keyring.
func (a *Agent) keyringProcess( func (a *Agent) keyringProcess(
method string, 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 { if a.server == nil {
return nil, fmt.Errorf("keyring operations must run against a server node") 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 // ListKeys lists out all keys installed on the collective Consul cluster. This
// includes both servers and clients in all DC's. // 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 := structs.KeyringRequest{}
args.AllowStale = true args.AllowStale = true
return a.keyringProcess("Internal.ListKeys", &args) return a.keyringProcess("Internal.ListKeys", &args)
} }
// InstallKey installs a new gossip encryption key // 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 := structs.KeyringRequest{Key: key}
args.AllowStale = true args.AllowStale = true
return a.keyringProcess("Internal.InstallKey", &args) return a.keyringProcess("Internal.InstallKey", &args)
} }
// UseKey changes the primary encryption key used to encrypt messages // 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 := structs.KeyringRequest{Key: key}
args.AllowStale = true args.AllowStale = true
return a.keyringProcess("Internal.UseKey", &args) return a.keyringProcess("Internal.UseKey", &args)
} }
// RemoveKey will remove a gossip encryption key from the keyring // 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 := structs.KeyringRequest{Key: key}
args.AllowStale = true args.AllowStale = true
return a.keyringProcess("Internal.RemoveKey", &args) return a.keyringProcess("Internal.RemoveKey", &args)

View File

@ -606,7 +606,7 @@ func (i *AgentRPC) handleReload(client *rpcClient, seq uint64) error {
func (i *AgentRPC) handleKeyring(client *rpcClient, seq uint64, cmd string) error { func (i *AgentRPC) handleKeyring(client *rpcClient, seq uint64, cmd string) error {
var req keyRequest var req keyRequest
var queryResp *structs.KeyringResponse var queryResp *structs.KeyringResponses
var resp keyResponse var resp keyResponse
var err error var err error
@ -636,14 +636,27 @@ func (i *AgentRPC) handleKeyring(client *rpcClient, seq uint64, cmd string) erro
Error: errToString(err), Error: errToString(err),
} }
if queryResp != nil { if resp.Messages == nil {
resp = keyResponse{ resp.Messages = make(map[string]string)
Messages: queryResp.Messages, }
Keys: queryResp.Keys, if resp.Keys == nil {
NumNodes: queryResp.NumNodes, resp.Keys = make(map[string]int)
NumResp: queryResp.NumResp, }
NumErr: queryResp.NumErr,
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) return client.Send(&header, resp)

View File

@ -1,10 +1,7 @@
package consul package consul
import ( import (
"fmt"
"github.com/hashicorp/consul/consul/structs" "github.com/hashicorp/consul/consul/structs"
"github.com/hashicorp/serf/serf"
) )
// Internal endpoint is used to query the miscellaneous info that // 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) return m.srv.UserEvent(args.Name, args.Payload)
} }
// TODO(ryanuber): Clean up all of these methods func (m *Internal) ListKeys(
func (m *Internal) InstallKey(args *structs.KeyringRequest, args *structs.KeyringRequest,
reply *structs.KeyringResponse) error { reply *structs.KeyringResponses) error {
var respLAN, respWAN *serf.KeyResponse respLAN, err := m.srv.KeyManagerLAN().ListKeys()
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
if err != nil { if err != nil {
return fmt.Errorf("failed rotating LAN keyring in %s: %s", return err
m.srv.config.Datacenter,
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 { if !args.Forwarded {
// Only perform WAN key rotation once. respWAN, err := m.srv.KeyManagerWAN().ListKeys()
respWAN, err = m.srv.KeyManagerWAN().InstallKey(args.Key)
if err != nil { if err != nil {
return err return err
} }
for node, msg := range respWAN.Messages { reply.Responses = append(reply.Responses, &structs.KeyringResponse{
reply.Messages["server."+node] = msg Datacenter: m.srv.config.Datacenter,
} Messages: respWAN.Messages,
reply.NumResp += respWAN.NumResp Keys: respWAN.Keys,
reply.NumErr += respWAN.NumErr NumResp: respWAN.NumResp,
reply.NumNodes += respWAN.NumNodes 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. // Mark key rotation as being already forwarded, then forward.
args.Forwarded = true args.Forwarded = true
@ -118,47 +135,30 @@ func (m *Internal) InstallKey(args *structs.KeyringRequest,
return nil return nil
} }
func (m *Internal) UseKey(args *structs.KeyringRequest, func (m *Internal) UseKey(
reply *structs.KeyringResponse) error { args *structs.KeyringRequest,
var respLAN, respWAN *serf.KeyResponse reply *structs.KeyringResponses) error {
var err error
if reply.Messages == nil { respLAN, _ := m.srv.KeyManagerLAN().UseKey(args.Key)
reply.Messages = make(map[string]string) reply.Responses = append(reply.Responses, &structs.KeyringResponse{
} Datacenter: m.srv.config.Datacenter,
if reply.Keys == nil { Messages: respLAN.Messages,
reply.Keys = make(map[string]int) Keys: respLAN.Keys,
} NumResp: respLAN.NumResp,
NumNodes: respLAN.NumNodes,
m.srv.setQueryMeta(&reply.QueryMeta) NumErr: respLAN.NumErr,
})
// 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)
}
if !args.Forwarded { if !args.Forwarded {
// Only perform WAN key rotation once. respWAN, _ := m.srv.KeyManagerWAN().UseKey(args.Key)
respWAN, err = m.srv.KeyManagerWAN().UseKey(args.Key) reply.Responses = append(reply.Responses, &structs.KeyringResponse{
if err != nil { Datacenter: m.srv.config.Datacenter,
return err Messages: respWAN.Messages,
} Keys: respWAN.Keys,
for node, msg := range respWAN.Messages { NumResp: respWAN.NumResp,
reply.Messages["server."+node] = msg NumNodes: respWAN.NumNodes,
} NumErr: respWAN.NumErr,
reply.NumResp += respWAN.NumResp })
reply.NumErr += respWAN.NumErr
reply.NumNodes += respWAN.NumNodes
// Mark key rotation as being already forwarded, then forward. // Mark key rotation as being already forwarded, then forward.
args.Forwarded = true args.Forwarded = true
@ -168,47 +168,30 @@ func (m *Internal) UseKey(args *structs.KeyringRequest,
return nil return nil
} }
func (m *Internal) RemoveKey(args *structs.KeyringRequest, func (m *Internal) RemoveKey(
reply *structs.KeyringResponse) error { args *structs.KeyringRequest,
var respLAN, respWAN *serf.KeyResponse reply *structs.KeyringResponses) error {
var err error
if reply.Messages == nil { respLAN, _ := m.srv.KeyManagerLAN().RemoveKey(args.Key)
reply.Messages = make(map[string]string) reply.Responses = append(reply.Responses, &structs.KeyringResponse{
} Datacenter: m.srv.config.Datacenter,
if reply.Keys == nil { Messages: respLAN.Messages,
reply.Keys = make(map[string]int) Keys: respLAN.Keys,
} NumResp: respLAN.NumResp,
NumNodes: respLAN.NumNodes,
m.srv.setQueryMeta(&reply.QueryMeta) NumErr: respLAN.NumErr,
})
// 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)
}
if !args.Forwarded { if !args.Forwarded {
// Only perform WAN key rotation once. respWAN, _ := m.srv.KeyManagerWAN().RemoveKey(args.Key)
respWAN, err = m.srv.KeyManagerWAN().RemoveKey(args.Key) reply.Responses = append(reply.Responses, &structs.KeyringResponse{
if err != nil { Datacenter: m.srv.config.Datacenter,
return err Messages: respWAN.Messages,
} Keys: respWAN.Keys,
for node, msg := range respWAN.Messages { NumResp: respWAN.NumResp,
reply.Messages["server."+node] = msg NumNodes: respWAN.NumNodes,
} NumErr: respWAN.NumErr,
reply.NumResp += respWAN.NumResp })
reply.NumErr += respWAN.NumErr
reply.NumNodes += respWAN.NumNodes
// Mark key rotation as being already forwarded, then forward. // Mark key rotation as being already forwarded, then forward.
args.Forwarded = true args.Forwarded = true
@ -217,53 +200,3 @@ func (m *Internal) RemoveKey(args *structs.KeyringRequest,
return nil 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
}

View File

@ -543,10 +543,14 @@ type KeyringRequest struct {
// KeyringResponse is a unified key response and can be used for install, // KeyringResponse is a unified key response and can be used for install,
// remove, use, as well as listing key queries. // remove, use, as well as listing key queries.
type KeyringResponse struct { type KeyringResponse struct {
Messages map[string]string Datacenter string
Keys map[string]int Messages map[string]string
NumNodes int Keys map[string]int
NumResp int NumNodes int
NumErr int NumResp int
QueryMeta NumErr int
}
type KeyringResponses struct {
Responses []*KeyringResponse
} }