coordinate: support `ResultsFilteredByACLs` flag/header (#11617)
This commit is contained in:
parent
aec3747ded
commit
8bb1b89554
|
@ -1405,10 +1405,11 @@ func (f *aclFilter) filterSessions(sessions *structs.Sessions) bool {
|
|||
}
|
||||
|
||||
// filterCoordinates is used to filter nodes in a coordinate dump based on ACL
|
||||
// rules.
|
||||
func (f *aclFilter) filterCoordinates(coords *structs.Coordinates) {
|
||||
// rules. Returns true if any elements were removed.
|
||||
func (f *aclFilter) filterCoordinates(coords *structs.Coordinates) bool {
|
||||
c := *coords
|
||||
var authzContext acl.AuthorizerContext
|
||||
var removed bool
|
||||
|
||||
for i := 0; i < len(c); i++ {
|
||||
c[i].FillAuthzContext(&authzContext)
|
||||
|
@ -1417,10 +1418,12 @@ func (f *aclFilter) filterCoordinates(coords *structs.Coordinates) {
|
|||
continue
|
||||
}
|
||||
f.logger.Debug("dropping node from result due to ACLs", "node", structs.NodeNameString(node, c[i].GetEnterpriseMeta()))
|
||||
removed = true
|
||||
c = append(c[:i], c[i+1:]...)
|
||||
i--
|
||||
}
|
||||
*coords = c
|
||||
return removed
|
||||
}
|
||||
|
||||
// filterIntentions is used to filter intentions based on ACL rules.
|
||||
|
@ -1827,7 +1830,7 @@ func filterACLWithAuthorizer(logger hclog.Logger, authorizer acl.Authorizer, sub
|
|||
filt.filterDatacenterCheckServiceNodes(&v.DatacenterNodes)
|
||||
|
||||
case *structs.IndexedCoordinates:
|
||||
filt.filterCoordinates(&v.Coordinates)
|
||||
v.QueryMeta.ResultsFilteredByACLs = filt.filterCoordinates(&v.Coordinates)
|
||||
|
||||
case *structs.IndexedHealthChecks:
|
||||
v.QueryMeta.ResultsFilteredByACLs = filt.filterHealthChecks(&v.HealthChecks)
|
||||
|
|
|
@ -2767,31 +2767,57 @@ service "bar" {
|
|||
|
||||
func TestACL_filterCoordinates(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Create some coordinates.
|
||||
coords := structs.Coordinates{
|
||||
&structs.Coordinate{
|
||||
Node: "node1",
|
||||
Coord: generateRandomCoordinate(),
|
||||
},
|
||||
&structs.Coordinate{
|
||||
Node: "node2",
|
||||
Coord: generateRandomCoordinate(),
|
||||
|
||||
logger := hclog.NewNullLogger()
|
||||
|
||||
makeList := func() *structs.IndexedCoordinates {
|
||||
return &structs.IndexedCoordinates{
|
||||
Coordinates: structs.Coordinates{
|
||||
{Node: "node1", Coord: generateRandomCoordinate()},
|
||||
{Node: "node2", Coord: generateRandomCoordinate()},
|
||||
},
|
||||
}
|
||||
|
||||
// Try permissive filtering.
|
||||
filt := newACLFilter(acl.AllowAll(), nil)
|
||||
filt.filterCoordinates(&coords)
|
||||
if len(coords) != 2 {
|
||||
t.Fatalf("bad: %#v", coords)
|
||||
}
|
||||
|
||||
// Try restrictive filtering
|
||||
filt = newACLFilter(acl.DenyAll(), nil)
|
||||
filt.filterCoordinates(&coords)
|
||||
if len(coords) != 0 {
|
||||
t.Fatalf("bad: %#v", coords)
|
||||
t.Run("allowed", func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
list := makeList()
|
||||
filterACLWithAuthorizer(logger, acl.AllowAll(), list)
|
||||
|
||||
require.Len(list.Coordinates, 2)
|
||||
require.False(list.QueryMeta.ResultsFilteredByACLs, "ResultsFilteredByACLs should be false")
|
||||
})
|
||||
|
||||
t.Run("allowed to read one node", func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
policy, err := acl.NewPolicyFromSource(`
|
||||
node "node1" {
|
||||
policy = "read"
|
||||
}
|
||||
`, acl.SyntaxLegacy, nil, nil)
|
||||
require.NoError(err)
|
||||
|
||||
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
||||
require.NoError(err)
|
||||
|
||||
list := makeList()
|
||||
filterACLWithAuthorizer(logger, authz, list)
|
||||
|
||||
require.Len(list.Coordinates, 1)
|
||||
require.True(list.QueryMeta.ResultsFilteredByACLs, "ResultsFilteredByACLs should be true")
|
||||
})
|
||||
|
||||
t.Run("denied", func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
list := makeList()
|
||||
filterACLWithAuthorizer(logger, acl.DenyAll(), list)
|
||||
|
||||
require.Empty(list.Coordinates)
|
||||
require.True(list.QueryMeta.ResultsFilteredByACLs, "ResultsFilteredByACLs should be true")
|
||||
})
|
||||
}
|
||||
|
||||
func TestACL_filterSessions(t *testing.T) {
|
||||
|
|
|
@ -452,6 +452,9 @@ func TestCoordinate_ListNodes_ACLFilter(t *testing.T) {
|
|||
if len(resp.Coordinates) != 1 || resp.Coordinates[0].Node != "foo" {
|
||||
t.Fatalf("bad: %#v", resp.Coordinates)
|
||||
}
|
||||
if !resp.QueryMeta.ResultsFilteredByACLs {
|
||||
t.Fatal("ResultsFilteredByACLs should be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoordinate_Node(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue