mirror of https://github.com/status-im/consul.git
consul: refactor keyring, repeat RPC calls to all DC's
This commit is contained in:
parent
cfbf2b4f94
commit
8dec2744da
|
@ -7,6 +7,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/consul/structs"
|
||||||
"github.com/hashicorp/memberlist"
|
"github.com/hashicorp/memberlist"
|
||||||
"github.com/hashicorp/serf/serf"
|
"github.com/hashicorp/serf/serf"
|
||||||
)
|
)
|
||||||
|
@ -61,78 +62,48 @@ func loadKeyringFile(c *serf.Config) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListKeysLAN returns the keys installed on the LAN gossip pool
|
// keyringProcess is used to abstract away the semantic similarities in
|
||||||
func (a *Agent) ListKeysLAN() (*serf.KeyResponse, error) {
|
// performing various operations on the encryption keyring.
|
||||||
if a.server != nil {
|
func (a *Agent) keyringProcess(
|
||||||
km := a.server.KeyManagerLAN()
|
method string,
|
||||||
return km.ListKeys()
|
args *structs.KeyringRequest) (*structs.KeyringResponse, error) {
|
||||||
|
|
||||||
|
var reply structs.KeyringResponse
|
||||||
|
if a.server == nil {
|
||||||
|
return nil, fmt.Errorf("keyring operations must run against a server node")
|
||||||
}
|
}
|
||||||
km := a.client.KeyManagerLAN()
|
if err := a.RPC(method, args, &reply); err != nil {
|
||||||
return km.ListKeys()
|
return &reply, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &reply, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListKeysWAN returns the keys installed on the WAN gossip pool
|
// ListKeys lists out all keys installed on the collective Consul cluster. This
|
||||||
func (a *Agent) ListKeysWAN() (*serf.KeyResponse, error) {
|
// includes both servers and clients in all DC's.
|
||||||
if a.server != nil {
|
func (a *Agent) ListKeys() (*structs.KeyringResponse, error) {
|
||||||
km := a.server.KeyManagerWAN()
|
args := structs.KeyringRequest{}
|
||||||
return km.ListKeys()
|
args.AllowStale = true
|
||||||
}
|
return a.keyringProcess("Internal.ListKeys", &args)
|
||||||
return nil, fmt.Errorf("WAN keyring not available on client node")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstallKeyWAN installs a new WAN gossip encryption key on server nodes
|
// InstallKey installs a new gossip encryption key
|
||||||
func (a *Agent) InstallKeyWAN(key string) (*serf.KeyResponse, error) {
|
func (a *Agent) InstallKey(key string) (*structs.KeyringResponse, error) {
|
||||||
if a.server != nil {
|
args := structs.KeyringRequest{Key: key}
|
||||||
km := a.server.KeyManagerWAN()
|
args.AllowStale = true
|
||||||
return km.InstallKey(key)
|
return a.keyringProcess("Internal.InstallKey", &args)
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("WAN keyring not available on client node")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstallKeyLAN installs a new LAN gossip encryption key on all nodes
|
// UseKey changes the primary encryption key used to encrypt messages
|
||||||
func (a *Agent) InstallKeyLAN(key string) (*serf.KeyResponse, error) {
|
func (a *Agent) UseKey(key string) (*structs.KeyringResponse, error) {
|
||||||
if a.server != nil {
|
args := structs.KeyringRequest{Key: key}
|
||||||
km := a.server.KeyManagerLAN()
|
args.AllowStale = true
|
||||||
return km.InstallKey(key)
|
return a.keyringProcess("Internal.UseKey", &args)
|
||||||
}
|
|
||||||
km := a.client.KeyManagerLAN()
|
|
||||||
return km.InstallKey(key)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UseKeyWAN changes the primary WAN gossip encryption key on server nodes
|
// RemoveKey will remove a gossip encryption key from the keyring
|
||||||
func (a *Agent) UseKeyWAN(key string) (*serf.KeyResponse, error) {
|
func (a *Agent) RemoveKey(key string) (*structs.KeyringResponse, error) {
|
||||||
if a.server != nil {
|
args := structs.KeyringRequest{Key: key}
|
||||||
km := a.server.KeyManagerWAN()
|
args.AllowStale = true
|
||||||
return km.UseKey(key)
|
return a.keyringProcess("Internal.RemoveKey", &args)
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("WAN keyring not available on client node")
|
|
||||||
}
|
|
||||||
|
|
||||||
// UseKeyLAN changes the primary LAN gossip encryption key on all nodes
|
|
||||||
func (a *Agent) UseKeyLAN(key string) (*serf.KeyResponse, error) {
|
|
||||||
if a.server != nil {
|
|
||||||
km := a.server.KeyManagerLAN()
|
|
||||||
return km.UseKey(key)
|
|
||||||
}
|
|
||||||
km := a.client.KeyManagerLAN()
|
|
||||||
return km.UseKey(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveKeyWAN removes a WAN gossip encryption key on server nodes
|
|
||||||
func (a *Agent) RemoveKeyWAN(key string) (*serf.KeyResponse, error) {
|
|
||||||
if a.server != nil {
|
|
||||||
km := a.server.KeyManagerWAN()
|
|
||||||
return km.RemoveKey(key)
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("WAN keyring not available on client node")
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveKeyLAN removes a LAN gossip encryption key on all nodes
|
|
||||||
func (a *Agent) RemoveKeyLAN(key string) (*serf.KeyResponse, error) {
|
|
||||||
if a.server != nil {
|
|
||||||
km := a.server.KeyManagerLAN()
|
|
||||||
return km.RemoveKey(key)
|
|
||||||
}
|
|
||||||
km := a.client.KeyManagerLAN()
|
|
||||||
return km.RemoveKey(key)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,15 +24,17 @@ package agent
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/hashicorp/go-msgpack/codec"
|
|
||||||
"github.com/hashicorp/logutils"
|
|
||||||
"github.com/hashicorp/serf/serf"
|
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/consul/structs"
|
||||||
|
"github.com/hashicorp/go-msgpack/codec"
|
||||||
|
"github.com/hashicorp/logutils"
|
||||||
|
"github.com/hashicorp/serf/serf"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -51,14 +53,10 @@ const (
|
||||||
leaveCommand = "leave"
|
leaveCommand = "leave"
|
||||||
statsCommand = "stats"
|
statsCommand = "stats"
|
||||||
reloadCommand = "reload"
|
reloadCommand = "reload"
|
||||||
listKeysLANCommand = "list-keys-lan"
|
installKeyCommand = "install-key"
|
||||||
listKeysWANCommand = "list-keys-wan"
|
useKeyCommand = "use-key"
|
||||||
installKeyLANCommand = "install-key-lan"
|
removeKeyCommand = "remove-key"
|
||||||
installKeyWANCommand = "install-key-wan"
|
listKeysCommand = "list-keys"
|
||||||
useKeyLANCommand = "use-key-lan"
|
|
||||||
useKeyWANCommand = "use-key-wan"
|
|
||||||
removeKeyLANCommand = "remove-key-lan"
|
|
||||||
removeKeyWANCommand = "remove-key-wan"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -117,10 +115,10 @@ type keyRequest struct {
|
||||||
|
|
||||||
type keyResponse struct {
|
type keyResponse struct {
|
||||||
Messages map[string]string
|
Messages map[string]string
|
||||||
|
Keys map[string]int
|
||||||
NumNodes int
|
NumNodes int
|
||||||
NumResp int
|
NumResp int
|
||||||
NumErr int
|
NumErr int
|
||||||
Keys map[string]int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type membersResponse struct {
|
type membersResponse struct {
|
||||||
|
@ -393,17 +391,8 @@ func (i *AgentRPC) handleRequest(client *rpcClient, reqHeader *requestHeader) er
|
||||||
case reloadCommand:
|
case reloadCommand:
|
||||||
return i.handleReload(client, seq)
|
return i.handleReload(client, seq)
|
||||||
|
|
||||||
case listKeysLANCommand, listKeysWANCommand:
|
case installKeyCommand, useKeyCommand, removeKeyCommand, listKeysCommand:
|
||||||
return i.handleListKeys(client, seq, command)
|
return i.handleKeyring(client, seq, command)
|
||||||
|
|
||||||
case installKeyLANCommand, installKeyWANCommand:
|
|
||||||
return i.handleGossipKeyChange(client, seq, command)
|
|
||||||
|
|
||||||
case useKeyLANCommand, useKeyWANCommand:
|
|
||||||
return i.handleGossipKeyChange(client, seq, command)
|
|
||||||
|
|
||||||
case removeKeyLANCommand, removeKeyWANCommand:
|
|
||||||
return i.handleGossipKeyChange(client, seq, command)
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
respHeader := responseHeader{Seq: seq, Error: unsupportedCommand}
|
respHeader := responseHeader{Seq: seq, Error: unsupportedCommand}
|
||||||
|
@ -615,56 +604,27 @@ func (i *AgentRPC) handleReload(client *rpcClient, seq uint64) error {
|
||||||
return client.Send(&resp, nil)
|
return client.Send(&resp, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *AgentRPC) handleListKeys(client *rpcClient, seq uint64, cmd string) error {
|
func (i *AgentRPC) handleKeyring(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,
|
|
||||||
Error: errToString(err),
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := keyResponse{
|
|
||||||
Messages: queryResp.Messages,
|
|
||||||
Keys: queryResp.Keys,
|
|
||||||
NumResp: queryResp.NumResp,
|
|
||||||
NumErr: queryResp.NumErr,
|
|
||||||
NumNodes: queryResp.NumNodes,
|
|
||||||
}
|
|
||||||
|
|
||||||
return client.Send(&header, &resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *AgentRPC) handleGossipKeyChange(client *rpcClient, seq uint64, cmd string) error {
|
|
||||||
var req keyRequest
|
var req keyRequest
|
||||||
|
var queryResp *structs.KeyringResponse
|
||||||
var resp keyResponse
|
var resp keyResponse
|
||||||
var queryResp *serf.KeyResponse
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
if cmd != listKeysCommand {
|
||||||
if err = client.dec.Decode(&req); err != nil {
|
if err = client.dec.Decode(&req); err != nil {
|
||||||
return fmt.Errorf("decode failed: %v", err)
|
return fmt.Errorf("decode failed: %v", err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch cmd {
|
switch cmd {
|
||||||
case installKeyWANCommand:
|
case listKeysCommand:
|
||||||
queryResp, err = i.agent.InstallKeyWAN(req.Key)
|
queryResp, err = i.agent.ListKeys()
|
||||||
case installKeyLANCommand:
|
case installKeyCommand:
|
||||||
queryResp, err = i.agent.InstallKeyLAN(req.Key)
|
queryResp, err = i.agent.InstallKey(req.Key)
|
||||||
case useKeyWANCommand:
|
case useKeyCommand:
|
||||||
queryResp, err = i.agent.UseKeyWAN(req.Key)
|
queryResp, err = i.agent.UseKey(req.Key)
|
||||||
case useKeyLANCommand:
|
case removeKeyCommand:
|
||||||
queryResp, err = i.agent.UseKeyLAN(req.Key)
|
queryResp, err = i.agent.RemoveKey(req.Key)
|
||||||
case removeKeyWANCommand:
|
|
||||||
queryResp, err = i.agent.RemoveKeyWAN(req.Key)
|
|
||||||
case removeKeyLANCommand:
|
|
||||||
queryResp, err = i.agent.RemoveKeyLAN(req.Key)
|
|
||||||
default:
|
default:
|
||||||
respHeader := responseHeader{Seq: seq, Error: unsupportedCommand}
|
respHeader := responseHeader{Seq: seq, Error: unsupportedCommand}
|
||||||
client.Send(&respHeader, nil)
|
client.Send(&respHeader, nil)
|
||||||
|
@ -676,15 +636,17 @@ func (i *AgentRPC) handleGossipKeyChange(client *rpcClient, seq uint64, cmd stri
|
||||||
Error: errToString(err),
|
Error: errToString(err),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if queryResp != nil {
|
||||||
resp = keyResponse{
|
resp = keyResponse{
|
||||||
Messages: queryResp.Messages,
|
Messages: queryResp.Messages,
|
||||||
Keys: queryResp.Keys,
|
Keys: queryResp.Keys,
|
||||||
|
NumNodes: queryResp.NumNodes,
|
||||||
NumResp: queryResp.NumResp,
|
NumResp: queryResp.NumResp,
|
||||||
NumErr: queryResp.NumErr,
|
NumErr: queryResp.NumErr,
|
||||||
NumNodes: queryResp.NumNodes,
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return client.Send(&header, &resp)
|
return client.Send(&header, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to convert an error to a string representation
|
// Used to convert an error to a string representation
|
||||||
|
|
|
@ -176,60 +176,44 @@ func (c *RPCClient) WANMembers() ([]Member, error) {
|
||||||
return resp.Members, err
|
return resp.Members, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RPCClient) ListKeysLAN() (map[string]int, int, map[string]string, error) {
|
func (c *RPCClient) ListKeys() (map[string]int, int, map[string]string, error) {
|
||||||
header := requestHeader{
|
header := requestHeader{
|
||||||
Command: listKeysLANCommand,
|
Command: listKeysCommand,
|
||||||
Seq: c.getSeq(),
|
Seq: c.getSeq(),
|
||||||
}
|
}
|
||||||
resp := new(keyResponse)
|
resp := new(keyResponse)
|
||||||
|
|
||||||
err := c.genericRPC(&header, nil, resp)
|
err := c.genericRPC(&header, nil, resp)
|
||||||
return resp.Keys, resp.NumNodes, resp.Messages, err
|
return resp.Keys, resp.NumNodes, resp.Messages, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RPCClient) ListKeysWAN() (map[string]int, int, map[string]string, error) {
|
func (c *RPCClient) InstallKey(key string) (map[string]string, error) {
|
||||||
header := requestHeader{
|
header := requestHeader{
|
||||||
Command: listKeysWANCommand,
|
Command: installKeyCommand,
|
||||||
Seq: c.getSeq(),
|
Seq: c.getSeq(),
|
||||||
}
|
}
|
||||||
resp := new(keyResponse)
|
|
||||||
|
|
||||||
err := c.genericRPC(&header, nil, resp)
|
|
||||||
return resp.Keys, resp.NumNodes, resp.Messages, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *RPCClient) InstallKeyWAN(key string) (map[string]string, error) {
|
|
||||||
return c.changeGossipKey(key, installKeyWANCommand)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *RPCClient) InstallKeyLAN(key string) (map[string]string, error) {
|
|
||||||
return c.changeGossipKey(key, installKeyLANCommand)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *RPCClient) UseKeyWAN(key string) (map[string]string, error) {
|
|
||||||
return c.changeGossipKey(key, useKeyWANCommand)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *RPCClient) UseKeyLAN(key string) (map[string]string, error) {
|
|
||||||
return c.changeGossipKey(key, useKeyLANCommand)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *RPCClient) RemoveKeyWAN(key string) (map[string]string, error) {
|
|
||||||
return c.changeGossipKey(key, removeKeyWANCommand)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *RPCClient) RemoveKeyLAN(key string) (map[string]string, error) {
|
|
||||||
return c.changeGossipKey(key, removeKeyLANCommand)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *RPCClient) changeGossipKey(key, cmd string) (map[string]string, error) {
|
|
||||||
header := requestHeader{
|
|
||||||
Command: cmd,
|
|
||||||
Seq: c.getSeq(),
|
|
||||||
}
|
|
||||||
|
|
||||||
req := keyRequest{key}
|
req := keyRequest{key}
|
||||||
|
resp := new(keyResponse)
|
||||||
|
err := c.genericRPC(&header, &req, resp)
|
||||||
|
return resp.Messages, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *RPCClient) UseKey(key string) (map[string]string, error) {
|
||||||
|
header := requestHeader{
|
||||||
|
Command: useKeyCommand,
|
||||||
|
Seq: c.getSeq(),
|
||||||
|
}
|
||||||
|
req := keyRequest{key}
|
||||||
|
resp := new(keyResponse)
|
||||||
|
err := c.genericRPC(&header, &req, resp)
|
||||||
|
return resp.Messages, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *RPCClient) RemoveKey(key string) (map[string]string, error) {
|
||||||
|
header := requestHeader{
|
||||||
|
Command: removeKeyCommand,
|
||||||
|
Seq: c.getSeq(),
|
||||||
|
}
|
||||||
|
req := keyRequest{key}
|
||||||
resp := new(keyResponse)
|
resp := new(keyResponse)
|
||||||
err := c.genericRPC(&header, &req, resp)
|
err := c.genericRPC(&header, &req, resp)
|
||||||
return resp.Messages, err
|
return resp.Messages, err
|
||||||
|
|
|
@ -106,59 +106,34 @@ func (c *KeyringCommand) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
if listKeys {
|
if listKeys {
|
||||||
if wan {
|
c.Ui.Info("Asking all members for installed keys...")
|
||||||
c.Ui.Info("Asking all WAN members for installed keys...")
|
return c.listKeysOperation(client.ListKeys)
|
||||||
return c.listKeysOperation(client.ListKeysWAN)
|
|
||||||
}
|
|
||||||
c.Ui.Info("Asking all LAN members for installed keys...")
|
|
||||||
return c.listKeysOperation(client.ListKeysLAN)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if installKey != "" {
|
if installKey != "" {
|
||||||
if wan {
|
c.Ui.Info("Installing new gossip encryption key...")
|
||||||
c.Ui.Info("Installing new WAN gossip encryption key...")
|
if rval := c.keyOperation(installKey, client.InstallKey); rval != 0 {
|
||||||
if rval := c.keyOperation(installKey, client.InstallKeyWAN); rval != 0 {
|
|
||||||
return rval
|
return rval
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
c.Ui.Info("Installing new LAN gossip encryption key...")
|
|
||||||
if rval := c.keyOperation(installKey, client.InstallKeyLAN); rval != 0 {
|
|
||||||
return rval
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.Ui.Info("Successfully installed key!")
|
c.Ui.Info("Successfully installed key!")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if useKey != "" {
|
if useKey != "" {
|
||||||
if wan {
|
c.Ui.Info("Changing primary gossip encryption key...")
|
||||||
c.Ui.Info("Changing primary WAN gossip encryption key...")
|
if rval := c.keyOperation(useKey, client.UseKey); rval != 0 {
|
||||||
if rval := c.keyOperation(useKey, client.UseKeyWAN); rval != 0 {
|
|
||||||
return rval
|
return rval
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
c.Ui.Info("Changing primary LAN gossip encryption key...")
|
|
||||||
if rval := c.keyOperation(useKey, client.UseKeyLAN); rval != 0 {
|
|
||||||
return rval
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.Ui.Info("Successfully changed primary key!")
|
c.Ui.Info("Successfully changed primary key!")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if removeKey != "" {
|
if removeKey != "" {
|
||||||
if wan {
|
c.Ui.Info("Removing gossip encryption key...")
|
||||||
c.Ui.Info("Removing WAN gossip encryption key...")
|
if rval := c.keyOperation(removeKey, client.RemoveKey); rval != 0 {
|
||||||
if rval := c.keyOperation(removeKey, client.RemoveKeyWAN); rval != 0 {
|
|
||||||
return rval
|
return rval
|
||||||
}
|
}
|
||||||
} else {
|
c.Ui.Info("Successfully removed gossip encryption key!")
|
||||||
c.Ui.Info("Removing LAN gossip encryption key...")
|
|
||||||
if rval := c.keyOperation(removeKey, client.RemoveKeyLAN); rval != 0 {
|
|
||||||
return rval
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.Ui.Info("Successfully removed key!")
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
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
|
||||||
|
@ -62,3 +65,205 @@ func (m *Internal) EventFire(args *structs.EventFireRequest,
|
||||||
// Fire the event
|
// Fire the event
|
||||||
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) InstallKey(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().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 {
|
||||||
|
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().InstallKey(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
|
||||||
|
|
||||||
|
// Mark key rotation as being already forwarded, then forward.
|
||||||
|
args.Forwarded = true
|
||||||
|
return m.srv.forwardAll("Internal.InstallKey", args, reply)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Internal) UseKey(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().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 {
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Mark key rotation as being already forwarded, then forward.
|
||||||
|
args.Forwarded = true
|
||||||
|
return m.srv.forwardAll("Internal.UseKey", args, reply)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Internal) RemoveKey(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().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 {
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Mark key rotation as being already forwarded, then forward.
|
||||||
|
args.Forwarded = true
|
||||||
|
return m.srv.forwardAll("Internal.RemoveKey", args, reply)
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -223,6 +223,18 @@ func (s *Server) forwardDC(method, dc string, args interface{}, reply interface{
|
||||||
return s.connPool.RPC(server.Addr, server.Version, method, args, reply)
|
return s.connPool.RPC(server.Addr, server.Version, method, args, reply)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// forwardAll forwards a single RPC call to every known datacenter.
|
||||||
|
func (s *Server) forwardAll(method string, args, reply interface{}) error {
|
||||||
|
for dc, _ := range s.remoteConsuls {
|
||||||
|
if dc != s.config.Datacenter {
|
||||||
|
if err := s.forwardDC(method, dc, args, reply); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// raftApply is used to encode a message, run it through raft, and return
|
// raftApply is used to encode a message, run it through raft, and return
|
||||||
// the FSM response along with any errors
|
// the FSM response along with any errors
|
||||||
func (s *Server) raftApply(t structs.MessageType, msg interface{}) (interface{}, error) {
|
func (s *Server) raftApply(t structs.MessageType, msg interface{}) (interface{}, error) {
|
||||||
|
|
|
@ -531,3 +531,22 @@ func Encode(t MessageType, msg interface{}) ([]byte, error) {
|
||||||
err := codec.NewEncoder(&buf, msgpackHandle).Encode(msg)
|
err := codec.NewEncoder(&buf, msgpackHandle).Encode(msg)
|
||||||
return buf.Bytes(), err
|
return buf.Bytes(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KeyringRequest encapsulates a request to modify an encryption keyring.
|
||||||
|
// It can be used for install, remove, or use key type operations.
|
||||||
|
type KeyringRequest struct {
|
||||||
|
Key string
|
||||||
|
Forwarded bool
|
||||||
|
QueryOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue