2014-04-27 19:56:06 +00:00
|
|
|
package consul
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/hashicorp/consul/consul/structs"
|
2014-10-02 06:09:00 +00:00
|
|
|
"github.com/hashicorp/serf/serf"
|
2014-04-27 19:56:06 +00:00
|
|
|
)
|
|
|
|
|
2014-04-28 21:44:36 +00:00
|
|
|
// Internal endpoint is used to query the miscellaneous info that
|
2014-04-27 19:56:06 +00:00
|
|
|
// does not necessarily fit into the other systems. It is also
|
|
|
|
// used to hold undocumented APIs that users should not rely on.
|
2014-04-28 21:44:36 +00:00
|
|
|
type Internal struct {
|
2014-04-27 19:56:06 +00:00
|
|
|
srv *Server
|
|
|
|
}
|
|
|
|
|
|
|
|
// ChecksInState is used to get all the checks in a given state
|
2014-04-28 21:44:36 +00:00
|
|
|
func (m *Internal) NodeInfo(args *structs.NodeSpecificRequest,
|
2014-04-27 19:56:06 +00:00
|
|
|
reply *structs.IndexedNodeDump) error {
|
2014-04-28 21:44:36 +00:00
|
|
|
if done, err := m.srv.forward("Internal.NodeInfo", args, args, reply); done {
|
2014-04-27 19:56:06 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the state specific checks
|
|
|
|
state := m.srv.fsm.State()
|
|
|
|
return m.srv.blockingRPC(&args.QueryOptions,
|
|
|
|
&reply.QueryMeta,
|
|
|
|
state.QueryTables("NodeInfo"),
|
|
|
|
func() error {
|
|
|
|
reply.Index, reply.Dump = state.NodeInfo(args.Node)
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// ChecksInState is used to get all the checks in a given state
|
2014-04-28 21:44:36 +00:00
|
|
|
func (m *Internal) NodeDump(args *structs.DCSpecificRequest,
|
2014-04-27 19:56:06 +00:00
|
|
|
reply *structs.IndexedNodeDump) error {
|
2014-04-28 21:44:36 +00:00
|
|
|
if done, err := m.srv.forward("Internal.NodeDump", args, args, reply); done {
|
2014-04-27 19:56:06 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the state specific checks
|
|
|
|
state := m.srv.fsm.State()
|
|
|
|
return m.srv.blockingRPC(&args.QueryOptions,
|
|
|
|
&reply.QueryMeta,
|
|
|
|
state.QueryTables("NodeDump"),
|
|
|
|
func() error {
|
|
|
|
reply.Index, reply.Dump = state.NodeDump()
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
2014-08-28 22:00:49 +00:00
|
|
|
|
|
|
|
// EventFire is a bit of an odd endpoint, but it allows for a cross-DC RPC
|
|
|
|
// call to fire an event. The primary use case is to enable user events being
|
|
|
|
// triggered in a remote DC.
|
|
|
|
func (m *Internal) EventFire(args *structs.EventFireRequest,
|
|
|
|
reply *structs.EventFireResponse) error {
|
|
|
|
if done, err := m.srv.forward("Internal.EventFire", args, args, reply); done {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the query meta data
|
|
|
|
m.srv.setQueryMeta(&reply.QueryMeta)
|
|
|
|
|
|
|
|
// Fire the event
|
|
|
|
return m.srv.UserEvent(args.Name, args.Payload)
|
|
|
|
}
|
2014-09-24 23:39:14 +00:00
|
|
|
|
2014-09-25 07:22:06 +00:00
|
|
|
// ListKeys will query the WAN and LAN gossip keyrings of all nodes, adding
|
|
|
|
// results into a collective response as we go.
|
2014-09-25 01:30:34 +00:00
|
|
|
func (m *Internal) ListKeys(
|
|
|
|
args *structs.KeyringRequest,
|
|
|
|
reply *structs.KeyringResponses) error {
|
2014-09-24 23:39:14 +00:00
|
|
|
|
2014-09-30 06:19:53 +00:00
|
|
|
dc := m.srv.config.Datacenter
|
2014-09-25 01:30:34 +00:00
|
|
|
respLAN, err := m.srv.KeyManagerLAN().ListKeys()
|
2014-09-30 06:19:53 +00:00
|
|
|
ingestKeyringResponse(respLAN, reply, dc, false, err)
|
2014-09-24 23:39:14 +00:00
|
|
|
|
|
|
|
if !args.Forwarded {
|
2014-09-25 01:30:34 +00:00
|
|
|
respWAN, err := m.srv.KeyManagerWAN().ListKeys()
|
2014-09-30 06:19:53 +00:00
|
|
|
ingestKeyringResponse(respWAN, reply, dc, true, err)
|
2014-09-24 23:39:14 +00:00
|
|
|
|
|
|
|
args.Forwarded = true
|
2014-10-02 06:09:00 +00:00
|
|
|
m.srv.globalRPC("Internal.ListKeys", args, reply)
|
2014-09-24 23:39:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-09-25 07:22:06 +00:00
|
|
|
// InstallKey broadcasts a new encryption key to all nodes. This involves
|
|
|
|
// installing a new key on every node across all datacenters.
|
2014-09-25 01:30:34 +00:00
|
|
|
func (m *Internal) InstallKey(
|
|
|
|
args *structs.KeyringRequest,
|
|
|
|
reply *structs.KeyringResponses) error {
|
2014-09-24 23:39:14 +00:00
|
|
|
|
2014-09-30 06:19:53 +00:00
|
|
|
dc := m.srv.config.Datacenter
|
2014-09-25 07:22:06 +00:00
|
|
|
respLAN, err := m.srv.KeyManagerLAN().InstallKey(args.Key)
|
2014-09-30 06:19:53 +00:00
|
|
|
ingestKeyringResponse(respLAN, reply, dc, false, err)
|
2014-09-24 23:39:14 +00:00
|
|
|
|
|
|
|
if !args.Forwarded {
|
2014-09-25 07:22:06 +00:00
|
|
|
respWAN, err := m.srv.KeyManagerWAN().InstallKey(args.Key)
|
2014-09-30 06:19:53 +00:00
|
|
|
ingestKeyringResponse(respWAN, reply, dc, true, err)
|
2014-09-24 23:39:14 +00:00
|
|
|
|
|
|
|
args.Forwarded = true
|
2014-10-02 06:09:00 +00:00
|
|
|
m.srv.globalRPC("Internal.InstallKey", args, reply)
|
2014-09-24 23:39:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-09-25 07:22:06 +00:00
|
|
|
// UseKey instructs all nodes to change the key they are using to
|
|
|
|
// encrypt gossip messages.
|
2014-09-25 01:30:34 +00:00
|
|
|
func (m *Internal) UseKey(
|
|
|
|
args *structs.KeyringRequest,
|
|
|
|
reply *structs.KeyringResponses) error {
|
2014-09-24 23:39:14 +00:00
|
|
|
|
2014-09-30 06:19:53 +00:00
|
|
|
dc := m.srv.config.Datacenter
|
2014-09-25 07:22:06 +00:00
|
|
|
respLAN, err := m.srv.KeyManagerLAN().UseKey(args.Key)
|
2014-09-30 06:19:53 +00:00
|
|
|
ingestKeyringResponse(respLAN, reply, dc, false, err)
|
2014-09-24 23:39:14 +00:00
|
|
|
|
|
|
|
if !args.Forwarded {
|
2014-09-25 07:22:06 +00:00
|
|
|
respWAN, err := m.srv.KeyManagerWAN().UseKey(args.Key)
|
2014-09-30 06:19:53 +00:00
|
|
|
ingestKeyringResponse(respWAN, reply, dc, true, err)
|
2014-09-24 23:39:14 +00:00
|
|
|
|
|
|
|
args.Forwarded = true
|
2014-10-02 06:09:00 +00:00
|
|
|
m.srv.globalRPC("Internal.UseKey", args, reply)
|
2014-09-24 23:39:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-09-25 07:22:06 +00:00
|
|
|
// RemoveKey instructs all nodes to drop the specified key from the keyring.
|
2014-09-25 01:30:34 +00:00
|
|
|
func (m *Internal) RemoveKey(
|
|
|
|
args *structs.KeyringRequest,
|
|
|
|
reply *structs.KeyringResponses) error {
|
2014-09-24 23:39:14 +00:00
|
|
|
|
2014-09-30 06:19:53 +00:00
|
|
|
dc := m.srv.config.Datacenter
|
2014-09-25 07:22:06 +00:00
|
|
|
respLAN, err := m.srv.KeyManagerLAN().RemoveKey(args.Key)
|
2014-09-30 06:19:53 +00:00
|
|
|
ingestKeyringResponse(respLAN, reply, dc, false, err)
|
2014-09-24 23:39:14 +00:00
|
|
|
|
|
|
|
if !args.Forwarded {
|
2014-09-25 07:22:06 +00:00
|
|
|
respWAN, err := m.srv.KeyManagerWAN().RemoveKey(args.Key)
|
2014-09-30 06:19:53 +00:00
|
|
|
ingestKeyringResponse(respWAN, reply, dc, true, err)
|
2014-09-24 23:39:14 +00:00
|
|
|
|
|
|
|
args.Forwarded = true
|
2014-10-02 06:09:00 +00:00
|
|
|
m.srv.globalRPC("Internal.RemoveKey", args, reply)
|
2014-09-24 23:39:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2014-10-02 06:09:00 +00:00
|
|
|
|
|
|
|
// ingestKeyringResponse is a helper method to pick the relative information
|
|
|
|
// from a Serf message and stuff it into a KeyringResponse.
|
|
|
|
func ingestKeyringResponse(
|
|
|
|
serfResp *serf.KeyResponse, reply *structs.KeyringResponses,
|
|
|
|
dc string, wan bool, err error) {
|
|
|
|
|
|
|
|
errStr := ""
|
|
|
|
if err != nil {
|
|
|
|
errStr = err.Error()
|
|
|
|
}
|
|
|
|
|
|
|
|
reply.Responses = append(reply.Responses, &structs.KeyringResponse{
|
|
|
|
WAN: wan,
|
|
|
|
Datacenter: dc,
|
|
|
|
Messages: serfResp.Messages,
|
|
|
|
Keys: serfResp.Keys,
|
|
|
|
NumNodes: serfResp.NumNodes,
|
|
|
|
Error: errStr,
|
|
|
|
})
|
|
|
|
}
|