From 63a2737caca7b821075a0b8fafaffe856e590ccf Mon Sep 17 00:00:00 2001 From: Ryan Uber Date: Thu, 11 Jun 2015 14:14:43 -0700 Subject: [PATCH] consul: testing acl filters in isolation --- consul/acl.go | 11 ++- consul/acl_test.go | 187 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+), 1 deletion(-) diff --git a/consul/acl.go b/consul/acl.go index ffd357ca8..32bb865ca 100644 --- a/consul/acl.go +++ b/consul/acl.go @@ -3,6 +3,7 @@ package consul import ( "errors" "log" + "os" "strings" "time" @@ -201,6 +202,14 @@ type aclFilter struct { logger *log.Logger } +// newAclFilter constructs a new aclFilter. +func newAclFilter(acl acl.ACL, logger *log.Logger) *aclFilter { + if logger == nil { + logger = log.New(os.Stdout, "", log.LstdFlags) + } + return &aclFilter{acl, logger} +} + // filterService is used to determine if a service is accessible for an ACL. func (f *aclFilter) filterService(service string) bool { if service == "" || service == ConsulServiceID { @@ -326,7 +335,7 @@ func (s *Server) filterACL(token string, subj interface{}) error { } // Create the filter - filt := &aclFilter{acl, s.logger} + filt := newAclFilter(acl, s.logger) switch v := subj.(type) { case *structs.IndexedHealthChecks: diff --git a/consul/acl_test.go b/consul/acl_test.go index 2fabcbee9..e5efedb97 100644 --- a/consul/acl_test.go +++ b/consul/acl_test.go @@ -674,6 +674,193 @@ func TestACL_MultiDC_Found(t *testing.T) { } } +func TestACL_filterHealthChecks(t *testing.T) { + // Create some health checks + hc := structs.HealthChecks{ + &structs.HealthCheck{ + Node: "node1", + CheckID: "check1", + ServiceName: "foo", + }, + } + + // Try permissive filtering + filt := newAclFilter(acl.AllowAll(), nil) + filt.filterHealthChecks(&hc) + if len(hc) != 1 { + t.Fatalf("bad: %#v", hc) + } + + // Try restrictive filtering + filt = newAclFilter(acl.DenyAll(), nil) + filt.filterHealthChecks(&hc) + if len(hc) != 0 { + t.Fatalf("bad: %#v", hc) + } +} + +func TestACL_filterServices(t *testing.T) { + // Create some services + services := structs.Services{ + "service1": []string{}, + "service2": []string{}, + } + + // Try permissive filtering + filt := newAclFilter(acl.AllowAll(), nil) + filt.filterServices(services) + if len(services) != 2 { + t.Fatalf("bad: %#v", services) + } + + // Try restrictive filtering + filt = newAclFilter(acl.DenyAll(), nil) + filt.filterServices(services) + if len(services) != 0 { + t.Fatalf("bad: %#v", services) + } +} + +func TestACL_filterServiceNodes(t *testing.T) { + // Create some service nodes + nodes := structs.ServiceNodes{ + structs.ServiceNode{ + Node: "node1", + ServiceName: "foo", + }, + } + + // Try permissive filtering + filt := newAclFilter(acl.AllowAll(), nil) + filt.filterServiceNodes(&nodes) + if len(nodes) != 1 { + t.Fatalf("bad: %#v", nodes) + } + + // Try restrictive filtering + filt = newAclFilter(acl.DenyAll(), nil) + filt.filterServiceNodes(&nodes) + if len(nodes) != 0 { + t.Fatalf("bad: %#v", nodes) + } +} + +func TestACL_filterNodeServices(t *testing.T) { + // Create some node services + services := structs.NodeServices{ + Node: structs.Node{ + Node: "node1", + }, + Services: map[string]*structs.NodeService{ + "foo": &structs.NodeService{ + ID: "foo", + Service: "foo", + }, + }, + } + + // Try permissive filtering + filt := newAclFilter(acl.AllowAll(), nil) + filt.filterNodeServices(&services) + if len(services.Services) != 1 { + t.Fatalf("bad: %#v", services.Services) + } + + // Try restrictive filtering + filt = newAclFilter(acl.DenyAll(), nil) + filt.filterNodeServices(&services) + if len(services.Services) != 0 { + t.Fatalf("bad: %#v", services.Services) + } +} + +func TestACL_filterCheckServiceNodes(t *testing.T) { + // Create some nodes + nodes := structs.CheckServiceNodes{ + structs.CheckServiceNode{ + Node: structs.Node{ + Node: "node1", + }, + Service: structs.NodeService{ + ID: "foo", + Service: "foo", + }, + Checks: structs.HealthChecks{ + &structs.HealthCheck{ + Node: "node1", + CheckID: "check1", + ServiceName: "foo", + }, + }, + }, + } + + // Try permissive filtering + filt := newAclFilter(acl.AllowAll(), nil) + filt.filterCheckServiceNodes(&nodes) + if len(nodes) != 1 { + t.Fatalf("bad: %#v", nodes) + } + if len(nodes[0].Checks) != 1 { + t.Fatalf("bad: %#v", nodes[0].Checks) + } + + // Try restrictive filtering + filt = newAclFilter(acl.DenyAll(), nil) + filt.filterCheckServiceNodes(&nodes) + if len(nodes) != 0 { + t.Fatalf("bad: %#v", nodes) + } +} + +func TestACL_filterNodeDump(t *testing.T) { + // Create a node dump + dump := structs.NodeDump{ + &structs.NodeInfo{ + Node: "node1", + Services: []*structs.NodeService{ + &structs.NodeService{ + ID: "foo", + Service: "foo", + }, + }, + Checks: []*structs.HealthCheck{ + &structs.HealthCheck{ + Node: "node1", + CheckID: "check1", + ServiceName: "foo", + }, + }, + }, + } + + // Try permissive filtering + filt := newAclFilter(acl.AllowAll(), nil) + filt.filterNodeDump(&dump) + if len(dump) != 1 { + t.Fatalf("bad: %#v", dump) + } + if len(dump[0].Services) != 1 { + t.Fatalf("bad: %#v", dump[0].Services) + } + if len(dump[0].Checks) != 1 { + t.Fatalf("bad: %#v", dump[0].Checks) + } + + // Try restrictive filtering + filt = newAclFilter(acl.DenyAll(), nil) + filt.filterNodeDump(&dump) + if len(dump) != 1 { + t.Fatalf("bad: %#v", dump) + } + if len(dump[0].Services) != 0 { + t.Fatalf("bad: %#v", dump[0].Services) + } + if len(dump[0].Checks) != 0 { + t.Fatalf("bad: %#v", dump[0].Checks) + } +} + var testACLPolicy = ` key "" { policy = "deny"