Make matchers part of the Policy interface (#2514)

* Make matchers part of the Policy interface

* Prevent race condition between rules and matchers

* Test also matchers in tests for Policy.Filter

* Compute `filterChanged` in v2 policy correctly

* Fix nil vs. empty list issue in v2 policy test

* policy/v2: always clear ssh map

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>

---------

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
Co-authored-by: Aras Ergus <aras.ergus@tngtech.com>
Co-authored-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
aergus-tng 2025-05-01 07:06:30 +02:00 committed by GitHub
parent eb1ecefd9e
commit 4651d06fa8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 89 additions and 43 deletions

View file

@ -270,18 +270,10 @@ func (node *Node) AppendToIPSet(build *netipx.IPSetBuilder) {
}
}
func (node *Node) CanAccess(filter []tailcfg.FilterRule, node2 *Node) bool {
func (node *Node) CanAccess(matchers []matcher.Match, node2 *Node) bool {
src := node.IPs()
allowedIPs := node2.IPs()
// TODO(kradalby): Regenerate this every time the filter change, instead of
// every time we use it.
// Part of #2416
matchers := make([]matcher.Match, len(filter))
for i, rule := range filter {
matchers[i] = matcher.MatchFromFilterRule(rule)
}
for _, matcher := range matchers {
if !matcher.SrcsContainsIPs(src...) {
continue

View file

@ -2,6 +2,7 @@ package types
import (
"fmt"
"github.com/juanfont/headscale/hscontrol/policy/matcher"
"net/netip"
"strings"
"testing"
@ -116,7 +117,8 @@ func Test_NodeCanAccess(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := tt.node1.CanAccess(tt.rules, &tt.node2)
matchers := matcher.MatchesFromFilterRules(tt.rules)
got := tt.node1.CanAccess(matchers, &tt.node2)
if got != tt.want {
t.Errorf("canAccess() failed: want (%t), got (%t)", tt.want, got)