diff --git a/agent/consul/intention_endpoint.go b/agent/consul/intention_endpoint.go new file mode 100644 index 000000000..7737d06dd --- /dev/null +++ b/agent/consul/intention_endpoint.go @@ -0,0 +1,36 @@ +package consul + +import ( + "github.com/hashicorp/consul/agent/consul/state" + "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/go-memdb" +) + +// Intention manages the Connect intentions. +type Intention struct { + // srv is a pointer back to the server. + srv *Server +} + +func (s *Intention) List( + args *structs.DCSpecificRequest, + reply *structs.IndexedIntentions) error { + // Forward if necessary + if done, err := s.srv.forward("Intention.List", args, args, reply); done { + return err + } + + return s.srv.blockingQuery( + &args.QueryOptions, &reply.QueryMeta, + func(ws memdb.WatchSet, state *state.Store) error { + index, ixns, err := state.Intentions(ws) + if err != nil { + return err + } + + reply.Index, reply.Intentions = index, ixns + // filterACL + return nil + }, + ) +} diff --git a/agent/consul/intention_endpoint_test.go b/agent/consul/intention_endpoint_test.go new file mode 100644 index 000000000..13242374c --- /dev/null +++ b/agent/consul/intention_endpoint_test.go @@ -0,0 +1,36 @@ +package consul + +import ( + "os" + "testing" + + "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/consul/testrpc" + "github.com/hashicorp/net-rpc-msgpackrpc" +) + +func TestIntentionList(t *testing.T) { + t.Parallel() + dir1, s1 := testServer(t) + defer os.RemoveAll(dir1) + defer s1.Shutdown() + + codec := rpcClient(t, s1) + defer codec.Close() + testrpc.WaitForLeader(t, s1.RPC, "dc1") + + // Test with no intentions inserted yet + { + req := &structs.DCSpecificRequest{ + Datacenter: "dc1", + } + var resp structs.IndexedIntentions + if err := msgpackrpc.CallWithCodec(codec, "Intention.List", req, &resp); err != nil { + t.Fatalf("err: %v", err) + } + + if len(resp.Intentions) != 0 { + t.Fatalf("bad: %v", resp) + } + } +} diff --git a/agent/consul/server_oss.go b/agent/consul/server_oss.go index 05c02e46c..e633c2699 100644 --- a/agent/consul/server_oss.go +++ b/agent/consul/server_oss.go @@ -5,6 +5,7 @@ func init() { registerEndpoint(func(s *Server) interface{} { return &Catalog{s} }) registerEndpoint(func(s *Server) interface{} { return NewCoordinate(s) }) registerEndpoint(func(s *Server) interface{} { return &Health{s} }) + registerEndpoint(func(s *Server) interface{} { return &Intention{s} }) registerEndpoint(func(s *Server) interface{} { return &Internal{s} }) registerEndpoint(func(s *Server) interface{} { return &KVS{s} }) registerEndpoint(func(s *Server) interface{} { return &Operator{s} }) diff --git a/agent/structs/intention.go b/agent/structs/intention.go index 646fb3f64..7837ad431 100644 --- a/agent/structs/intention.go +++ b/agent/structs/intention.go @@ -60,3 +60,12 @@ const ( // IntentionSourceConsul is a service within the Consul catalog. IntentionSourceConsul IntentionSourceType = "consul" ) + +// Intentions is a list of intentions. +type Intentions []*Intention + +// IndexedIntentions represents a list of intentions for RPC responses. +type IndexedIntentions struct { + Intentions Intentions + QueryMeta +}