consul: use keyring operation type to cut out duplicated logic

This commit is contained in:
Ryan Uber 2014-10-02 17:10:54 -07:00
parent 9556347609
commit 7b4b87ccf1
3 changed files with 44 additions and 64 deletions

View File

@ -84,26 +84,30 @@ func (a *Agent) keyringProcess(
func (a *Agent) ListKeys() (*structs.KeyringResponses, 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) args.Operation = structs.KeyringList
return a.keyringProcess("Internal.KeyringOperation", &args)
} }
// InstallKey installs a new gossip encryption key // InstallKey installs a new gossip encryption key
func (a *Agent) InstallKey(key string) (*structs.KeyringResponses, 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) args.Operation = structs.KeyringInstall
return a.keyringProcess("Internal.KeyringOperation", &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.KeyringResponses, 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) args.Operation = structs.KeyringUse
return a.keyringProcess("Internal.KeyringOperation", &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.KeyringResponses, 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) args.Operation = structs.KeyringRemove
return a.keyringProcess("Internal.KeyringOperation", &args)
} }

View File

@ -12,6 +12,15 @@ type Internal struct {
srv *Server srv *Server
} }
type KeyringOperation uint8
const (
listKeysOperation KeyringOperation = iota
installKeyOperation
useKeyOperation
removeKeyOperation
)
// ChecksInState is used to get all the checks in a given state // ChecksInState is used to get all the checks in a given state
func (m *Internal) NodeInfo(args *structs.NodeSpecificRequest, func (m *Internal) NodeInfo(args *structs.NodeSpecificRequest,
reply *structs.IndexedNodeDump) error { reply *structs.IndexedNodeDump) error {
@ -66,85 +75,42 @@ func (m *Internal) EventFire(args *structs.EventFireRequest,
// ListKeys will query the WAN and LAN gossip keyrings of all nodes, adding // ListKeys will query the WAN and LAN gossip keyrings of all nodes, adding
// results into a collective response as we go. // results into a collective response as we go.
func (m *Internal) ListKeys( func (m *Internal) KeyringOperation(
args *structs.KeyringRequest, args *structs.KeyringRequest,
reply *structs.KeyringResponses) error { reply *structs.KeyringResponses) error {
dc := m.srv.config.Datacenter dc := m.srv.config.Datacenter
respLAN, err := m.srv.KeyManagerLAN().ListKeys()
respLAN, err := m.doKeyringOperation(args, m.srv.KeyManagerLAN())
ingestKeyringResponse(respLAN, reply, dc, false, err) ingestKeyringResponse(respLAN, reply, dc, false, err)
if !args.Forwarded { if !args.Forwarded {
respWAN, err := m.srv.KeyManagerWAN().ListKeys() respWAN, err := m.doKeyringOperation(args, m.srv.KeyManagerWAN())
ingestKeyringResponse(respWAN, reply, dc, true, err) ingestKeyringResponse(respWAN, reply, dc, true, err)
args.Forwarded = true args.Forwarded = true
m.srv.globalRPC("Internal.ListKeys", args, reply) return m.srv.globalRPC("Internal.KeyringOperation", args, reply)
} }
return nil return nil
} }
// InstallKey broadcasts a new encryption key to all nodes. This involves func (m *Internal) doKeyringOperation(
// installing a new key on every node across all datacenters.
func (m *Internal) InstallKey(
args *structs.KeyringRequest, args *structs.KeyringRequest,
reply *structs.KeyringResponses) error { mgr *serf.KeyManager) (r *serf.KeyResponse, err error) {
dc := m.srv.config.Datacenter switch args.Operation {
respLAN, err := m.srv.KeyManagerLAN().InstallKey(args.Key) case structs.KeyringList:
ingestKeyringResponse(respLAN, reply, dc, false, err) r, err = mgr.ListKeys()
case structs.KeyringInstall:
if !args.Forwarded { r, err = mgr.InstallKey(args.Key)
respWAN, err := m.srv.KeyManagerWAN().InstallKey(args.Key) case structs.KeyringUse:
ingestKeyringResponse(respWAN, reply, dc, true, err) r, err = mgr.UseKey(args.Key)
case structs.KeyringRemove:
args.Forwarded = true r, err = mgr.RemoveKey(args.Key)
m.srv.globalRPC("Internal.InstallKey", args, reply)
} }
return nil return r, err
}
// UseKey instructs all nodes to change the key they are using to
// encrypt gossip messages.
func (m *Internal) UseKey(
args *structs.KeyringRequest,
reply *structs.KeyringResponses) error {
dc := m.srv.config.Datacenter
respLAN, err := m.srv.KeyManagerLAN().UseKey(args.Key)
ingestKeyringResponse(respLAN, reply, dc, false, err)
if !args.Forwarded {
respWAN, err := m.srv.KeyManagerWAN().UseKey(args.Key)
ingestKeyringResponse(respWAN, reply, dc, true, err)
args.Forwarded = true
m.srv.globalRPC("Internal.UseKey", args, reply)
}
return nil
}
// RemoveKey instructs all nodes to drop the specified key from the keyring.
func (m *Internal) RemoveKey(
args *structs.KeyringRequest,
reply *structs.KeyringResponses) error {
dc := m.srv.config.Datacenter
respLAN, err := m.srv.KeyManagerLAN().RemoveKey(args.Key)
ingestKeyringResponse(respLAN, reply, dc, false, err)
if !args.Forwarded {
respWAN, err := m.srv.KeyManagerWAN().RemoveKey(args.Key)
ingestKeyringResponse(respWAN, reply, dc, true, err)
args.Forwarded = true
m.srv.globalRPC("Internal.RemoveKey", args, reply)
}
return nil
} }
// ingestKeyringResponse is a helper method to pick the relative information // ingestKeyringResponse is a helper method to pick the relative information

View File

@ -554,9 +554,19 @@ type CompoundResponse interface {
New() interface{} New() interface{}
} }
type KeyringOp string
const (
KeyringList KeyringOp = "list"
KeyringInstall = "install"
KeyringUse = "use"
KeyringRemove = "remove"
)
// KeyringRequest encapsulates a request to modify an encryption keyring. // KeyringRequest encapsulates a request to modify an encryption keyring.
// It can be used for install, remove, or use key type operations. // It can be used for install, remove, or use key type operations.
type KeyringRequest struct { type KeyringRequest struct {
Operation KeyringOp
Key string Key string
Datacenter string Datacenter string
Forwarded bool Forwarded bool