mirror of
https://github.com/juanfont/headscale.git
synced 2026-01-23 02:24:10 +00:00
all: use new() builtin and slices utilities
Modernize code to use Go 1.26 features:
1. Replace ptr.To with the new() builtin:
Before: ptr.To(value)
After: new(value)
2. Replace append clone pattern with slices.Clone:
Before: copy := append([]T{}, slice...)
After: copy := slices.Clone(slice)
3. Replace manual contains loops with slices.Contains:
Before: for _, v := range slice { if v == target { return true } }
After: slices.Contains(slice, target)
The ptr.To function from tailscale.com/types/ptr is no longer
needed as Go 1.26's enhanced new() builtin accepts a value
argument and returns a pointer to a copy of that value.
Note: Auto-generated files (types_clone.go) are not modified
as they are generated by tailscale.com/cmd/cloner.
This commit is contained in:
parent
094faf7a6a
commit
3675b65504
22 changed files with 324 additions and 341 deletions
|
|
@ -13,7 +13,6 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
var mpp = func(pref string) *netip.Prefix {
|
||||
|
|
@ -488,8 +487,8 @@ func TestIPAllocatorNextNoReservedIPs(t *testing.T) {
|
|||
|
||||
alloc, err := NewIPAllocator(
|
||||
db,
|
||||
ptr.To(tsaddr.CGNATRange()),
|
||||
ptr.To(tsaddr.TailscaleULARange()),
|
||||
new(tsaddr.CGNATRange()),
|
||||
new(tsaddr.TailscaleULARange()),
|
||||
types.IPAllocationStrategySequential,
|
||||
)
|
||||
if err != nil {
|
||||
|
|
@ -497,17 +496,17 @@ func TestIPAllocatorNextNoReservedIPs(t *testing.T) {
|
|||
}
|
||||
|
||||
// Validate that we do not give out 100.100.100.100
|
||||
nextQuad100, err := alloc.next(na("100.100.100.99"), ptr.To(tsaddr.CGNATRange()))
|
||||
nextQuad100, err := alloc.next(na("100.100.100.99"), new(tsaddr.CGNATRange()))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, na("100.100.100.101"), *nextQuad100)
|
||||
|
||||
// Validate that we do not give out fd7a:115c:a1e0::53
|
||||
nextQuad100v6, err := alloc.next(na("fd7a:115c:a1e0::52"), ptr.To(tsaddr.TailscaleULARange()))
|
||||
nextQuad100v6, err := alloc.next(na("fd7a:115c:a1e0::52"), new(tsaddr.TailscaleULARange()))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, na("fd7a:115c:a1e0::54"), *nextQuad100v6)
|
||||
|
||||
// Validate that we do not give out fd7a:115c:a1e0::53
|
||||
nextChrome, err := alloc.next(na("100.115.91.255"), ptr.To(tsaddr.CGNATRange()))
|
||||
nextChrome, err := alloc.next(na("100.115.91.255"), new(tsaddr.CGNATRange()))
|
||||
t.Logf("chrome: %s", nextChrome.String())
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, na("100.115.94.0"), *nextChrome)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import (
|
|||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
func TestGetNode(t *testing.T) {
|
||||
|
|
@ -115,7 +114,7 @@ func TestExpireNode(t *testing.T) {
|
|||
Hostname: "testnode",
|
||||
UserID: &user.ID,
|
||||
RegisterMethod: util.RegisterMethodAuthKey,
|
||||
AuthKeyID: ptr.To(pak.ID),
|
||||
AuthKeyID: new(pak.ID),
|
||||
Expiry: &time.Time{},
|
||||
}
|
||||
db.DB.Save(node)
|
||||
|
|
@ -159,7 +158,7 @@ func TestSetTags(t *testing.T) {
|
|||
Hostname: "testnode",
|
||||
UserID: &user.ID,
|
||||
RegisterMethod: util.RegisterMethodAuthKey,
|
||||
AuthKeyID: ptr.To(pak.ID),
|
||||
AuthKeyID: new(pak.ID),
|
||||
}
|
||||
|
||||
trx := db.DB.Save(node)
|
||||
|
|
@ -443,7 +442,7 @@ func TestAutoApproveRoutes(t *testing.T) {
|
|||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: tt.routes,
|
||||
},
|
||||
IPv4: ptr.To(netip.MustParseAddr("100.64.0.1")),
|
||||
IPv4: new(netip.MustParseAddr("100.64.0.1")),
|
||||
}
|
||||
|
||||
err = adb.DB.Save(&node).Error
|
||||
|
|
@ -460,7 +459,7 @@ func TestAutoApproveRoutes(t *testing.T) {
|
|||
RoutableIPs: tt.routes,
|
||||
},
|
||||
Tags: []string{"tag:exit"},
|
||||
IPv4: ptr.To(netip.MustParseAddr("100.64.0.2")),
|
||||
IPv4: new(netip.MustParseAddr("100.64.0.2")),
|
||||
}
|
||||
|
||||
err = adb.DB.Save(&nodeTagged).Error
|
||||
|
|
@ -649,7 +648,7 @@ func TestListEphemeralNodes(t *testing.T) {
|
|||
Hostname: "test",
|
||||
UserID: &user.ID,
|
||||
RegisterMethod: util.RegisterMethodAuthKey,
|
||||
AuthKeyID: ptr.To(pak.ID),
|
||||
AuthKeyID: new(pak.ID),
|
||||
}
|
||||
|
||||
nodeEph := types.Node{
|
||||
|
|
@ -659,7 +658,7 @@ func TestListEphemeralNodes(t *testing.T) {
|
|||
Hostname: "ephemeral",
|
||||
UserID: &user.ID,
|
||||
RegisterMethod: util.RegisterMethodAuthKey,
|
||||
AuthKeyID: ptr.To(pakEph.ID),
|
||||
AuthKeyID: new(pakEph.ID),
|
||||
}
|
||||
|
||||
err = db.DB.Save(&node).Error
|
||||
|
|
@ -750,8 +749,8 @@ func TestNodeNaming(t *testing.T) {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = RegisterNodeForTest(tx, nodeInvalidHostname, ptr.To(mpp("100.64.0.66/32").Addr()), nil)
|
||||
_, err = RegisterNodeForTest(tx, nodeShortHostname, ptr.To(mpp("100.64.0.67/32").Addr()), nil)
|
||||
_, err = RegisterNodeForTest(tx, nodeInvalidHostname, new(mpp("100.64.0.66/32").Addr()), nil)
|
||||
_, err = RegisterNodeForTest(tx, nodeShortHostname, new(mpp("100.64.0.67/32").Addr()), nil)
|
||||
return err
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ func isTextUnmarshaler(rv reflect.Value) bool {
|
|||
}
|
||||
|
||||
func maybeInstantiatePtr(rv reflect.Value) {
|
||||
if rv.Kind() == reflect.Ptr && rv.IsNil() {
|
||||
if rv.Kind() == reflect.Pointer && rv.IsNil() {
|
||||
np := reflect.New(rv.Type().Elem())
|
||||
rv.Set(np)
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ func (TextSerialiser) Scan(ctx context.Context, field *schema.Field, dst reflect
|
|||
|
||||
// If the field is a pointer, we need to dereference it to get the actual type
|
||||
// so we do not end with a second pointer.
|
||||
if fieldValue.Elem().Kind() == reflect.Ptr {
|
||||
if fieldValue.Elem().Kind() == reflect.Pointer {
|
||||
fieldValue = fieldValue.Elem()
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ func (TextSerialiser) Scan(ctx context.Context, field *schema.Field, dst reflect
|
|||
// If it is not a pointer, we need to assign the value to the
|
||||
// field.
|
||||
dstField := field.ReflectValueOf(ctx, dst)
|
||||
if dstField.Kind() == reflect.Ptr {
|
||||
if dstField.Kind() == reflect.Pointer {
|
||||
dstField.Set(fieldValue)
|
||||
} else {
|
||||
dstField.Set(fieldValue.Elem())
|
||||
|
|
@ -86,7 +86,7 @@ func (TextSerialiser) Value(ctx context.Context, field *schema.Field, dst reflec
|
|||
// If the value is nil, we return nil, however, go nil values are not
|
||||
// always comparable, particularly when reflection is involved:
|
||||
// https://dev.to/arxeiss/in-go-nil-is-not-equal-to-nil-sometimes-jn8
|
||||
if v == nil || (reflect.ValueOf(v).Kind() == reflect.Ptr && reflect.ValueOf(v).IsNil()) {
|
||||
if v == nil || (reflect.ValueOf(v).Kind() == reflect.Pointer && reflect.ValueOf(v).IsNil()) {
|
||||
return nil, nil
|
||||
}
|
||||
b, err := v.MarshalText()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
func TestCreateAndDestroyUser(t *testing.T) {
|
||||
|
|
@ -79,7 +78,7 @@ func TestDestroyUserErrors(t *testing.T) {
|
|||
Hostname: "testnode",
|
||||
UserID: &user.ID,
|
||||
RegisterMethod: util.RegisterMethodAuthKey,
|
||||
AuthKeyID: ptr.To(pak.ID),
|
||||
AuthKeyID: new(pak.ID),
|
||||
}
|
||||
trx := db.DB.Save(&node)
|
||||
require.NoError(t, trx.Error)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import (
|
|||
"github.com/puzpuzpuz/xsync/v4"
|
||||
"github.com/rs/zerolog/log"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
var errConnectionClosed = errors.New("connection channel already closed")
|
||||
|
|
@ -136,7 +135,7 @@ func (b *LockFreeBatcher) RemoveNode(id types.NodeID, c chan<- *tailcfg.MapRespo
|
|||
// No active connections - keep the node entry alive for rapid reconnections
|
||||
// The node will get a fresh full map when it reconnects
|
||||
log.Debug().Caller().Uint64("node.id", id.Uint64()).Msg("Node disconnected from batcher because all connections removed, keeping entry for rapid reconnection")
|
||||
b.connected.Store(id, ptr.To(time.Now()))
|
||||
b.connected.Store(id, new(time.Now()))
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"net/netip"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
|
@ -327,7 +328,7 @@ func (ut *updateTracker) getStats(nodeID types.NodeID) UpdateStats {
|
|||
// Return a copy to avoid race conditions
|
||||
return UpdateStats{
|
||||
TotalUpdates: stats.TotalUpdates,
|
||||
UpdateSizes: append([]int{}, stats.UpdateSizes...),
|
||||
UpdateSizes: slices.Clone(stats.UpdateSizes),
|
||||
LastUpdate: stats.LastUpdate,
|
||||
}
|
||||
}
|
||||
|
|
@ -344,7 +345,7 @@ func (ut *updateTracker) getAllStats() map[types.NodeID]UpdateStats {
|
|||
for nodeID, stats := range ut.stats {
|
||||
result[nodeID] = UpdateStats{
|
||||
TotalUpdates: stats.TotalUpdates,
|
||||
UpdateSizes: append([]int{}, stats.UpdateSizes...),
|
||||
UpdateSizes: slices.Clone(stats.UpdateSizes),
|
||||
LastUpdate: stats.LastUpdate,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import (
|
|||
"github.com/juanfont/headscale/hscontrol/types"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/dnstype"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
var iap = func(ipStr string) *netip.Addr {
|
||||
|
|
@ -51,7 +50,7 @@ func TestDNSConfigMapResponse(t *testing.T) {
|
|||
mach := func(hostname, username string, userid uint) *types.Node {
|
||||
return &types.Node{
|
||||
Hostname: hostname,
|
||||
UserID: ptr.To(userid),
|
||||
UserID: new(userid),
|
||||
User: &types.User{
|
||||
Name: username,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
var ap = func(ipStr string) *netip.Addr {
|
||||
|
|
@ -1074,21 +1073,21 @@ func TestSSHPolicyRules(t *testing.T) {
|
|||
nodeUser1 := types.Node{
|
||||
Hostname: "user1-device",
|
||||
IPv4: ap("100.64.0.1"),
|
||||
UserID: ptr.To(uint(1)),
|
||||
User: ptr.To(users[0]),
|
||||
UserID: new(uint(1)),
|
||||
User: new(users[0]),
|
||||
}
|
||||
nodeUser2 := types.Node{
|
||||
Hostname: "user2-device",
|
||||
IPv4: ap("100.64.0.2"),
|
||||
UserID: ptr.To(uint(2)),
|
||||
User: ptr.To(users[1]),
|
||||
UserID: new(uint(2)),
|
||||
User: new(users[1]),
|
||||
}
|
||||
|
||||
taggedClient := types.Node{
|
||||
Hostname: "tagged-client",
|
||||
IPv4: ap("100.64.0.4"),
|
||||
UserID: ptr.To(uint(2)),
|
||||
User: ptr.To(users[1]),
|
||||
UserID: new(uint(2)),
|
||||
User: new(users[1]),
|
||||
Tags: []string{"tag:client"},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import (
|
|||
"gorm.io/gorm"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/ptr"
|
||||
"tailscale.com/util/must"
|
||||
)
|
||||
|
||||
|
|
@ -144,13 +143,13 @@ func TestReduceFilterRules(t *testing.T) {
|
|||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0:ab12:4843:2222:6273:2221"),
|
||||
User: ptr.To(users[0]),
|
||||
User: new(users[0]),
|
||||
},
|
||||
peers: types.Nodes{
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0:ab12:4843:2222:6273:2222"),
|
||||
User: ptr.To(users[0]),
|
||||
User: new(users[0]),
|
||||
},
|
||||
},
|
||||
want: []tailcfg.FilterRule{},
|
||||
|
|
@ -191,7 +190,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: ptr.To(users[1]),
|
||||
User: new(users[1]),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{
|
||||
netip.MustParsePrefix("10.33.0.0/16"),
|
||||
|
|
@ -202,7 +201,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||
&types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: ptr.To(users[1]),
|
||||
User: new(users[1]),
|
||||
},
|
||||
},
|
||||
want: []tailcfg.FilterRule{
|
||||
|
|
@ -283,19 +282,19 @@ func TestReduceFilterRules(t *testing.T) {
|
|||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: ptr.To(users[1]),
|
||||
User: new(users[1]),
|
||||
},
|
||||
peers: types.Nodes{
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: ptr.To(users[2]),
|
||||
User: new(users[2]),
|
||||
},
|
||||
// "internal" exit node
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.100"),
|
||||
IPv6: ap("fd7a:115c:a1e0::100"),
|
||||
User: ptr.To(users[3]),
|
||||
User: new(users[3]),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: tsaddr.ExitRoutes(),
|
||||
},
|
||||
|
|
@ -344,7 +343,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.100"),
|
||||
IPv6: ap("fd7a:115c:a1e0::100"),
|
||||
User: ptr.To(users[3]),
|
||||
User: new(users[3]),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: tsaddr.ExitRoutes(),
|
||||
},
|
||||
|
|
@ -353,12 +352,12 @@ func TestReduceFilterRules(t *testing.T) {
|
|||
&types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: ptr.To(users[2]),
|
||||
User: new(users[2]),
|
||||
},
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: ptr.To(users[1]),
|
||||
User: new(users[1]),
|
||||
},
|
||||
},
|
||||
want: []tailcfg.FilterRule{
|
||||
|
|
@ -453,7 +452,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.100"),
|
||||
IPv6: ap("fd7a:115c:a1e0::100"),
|
||||
User: ptr.To(users[3]),
|
||||
User: new(users[3]),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: tsaddr.ExitRoutes(),
|
||||
},
|
||||
|
|
@ -462,12 +461,12 @@ func TestReduceFilterRules(t *testing.T) {
|
|||
&types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: ptr.To(users[2]),
|
||||
User: new(users[2]),
|
||||
},
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: ptr.To(users[1]),
|
||||
User: new(users[1]),
|
||||
},
|
||||
},
|
||||
want: []tailcfg.FilterRule{
|
||||
|
|
@ -565,7 +564,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.100"),
|
||||
IPv6: ap("fd7a:115c:a1e0::100"),
|
||||
User: ptr.To(users[3]),
|
||||
User: new(users[3]),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{netip.MustParsePrefix("8.0.0.0/16"), netip.MustParsePrefix("16.0.0.0/16")},
|
||||
},
|
||||
|
|
@ -574,12 +573,12 @@ func TestReduceFilterRules(t *testing.T) {
|
|||
&types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: ptr.To(users[2]),
|
||||
User: new(users[2]),
|
||||
},
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: ptr.To(users[1]),
|
||||
User: new(users[1]),
|
||||
},
|
||||
},
|
||||
want: []tailcfg.FilterRule{
|
||||
|
|
@ -655,7 +654,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.100"),
|
||||
IPv6: ap("fd7a:115c:a1e0::100"),
|
||||
User: ptr.To(users[3]),
|
||||
User: new(users[3]),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{netip.MustParsePrefix("8.0.0.0/8"), netip.MustParsePrefix("16.0.0.0/8")},
|
||||
},
|
||||
|
|
@ -664,12 +663,12 @@ func TestReduceFilterRules(t *testing.T) {
|
|||
&types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: ptr.To(users[2]),
|
||||
User: new(users[2]),
|
||||
},
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: ptr.To(users[1]),
|
||||
User: new(users[1]),
|
||||
},
|
||||
},
|
||||
want: []tailcfg.FilterRule{
|
||||
|
|
@ -737,7 +736,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.100"),
|
||||
IPv6: ap("fd7a:115c:a1e0::100"),
|
||||
User: ptr.To(users[3]),
|
||||
User: new(users[3]),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{netip.MustParsePrefix("172.16.0.0/24")},
|
||||
},
|
||||
|
|
@ -747,7 +746,7 @@ func TestReduceFilterRules(t *testing.T) {
|
|||
&types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: ptr.To(users[1]),
|
||||
User: new(users[1]),
|
||||
},
|
||||
},
|
||||
want: []tailcfg.FilterRule{
|
||||
|
|
@ -804,13 +803,13 @@ func TestReduceFilterRules(t *testing.T) {
|
|||
node: &types.Node{
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: ptr.To(users[3]),
|
||||
User: new(users[3]),
|
||||
},
|
||||
peers: types.Nodes{
|
||||
&types.Node{
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: ptr.To(users[1]),
|
||||
User: new(users[1]),
|
||||
Hostinfo: &tailcfg.Hostinfo{
|
||||
RoutableIPs: []netip.Prefix{p("172.16.0.0/24"), p("10.10.11.0/24"), p("10.10.12.0/24")},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
func TestNodeCanApproveRoute(t *testing.T) {
|
||||
|
|
@ -25,24 +24,24 @@ func TestNodeCanApproveRoute(t *testing.T) {
|
|||
ID: 1,
|
||||
Hostname: "user1-device",
|
||||
IPv4: ap("100.64.0.1"),
|
||||
UserID: ptr.To(uint(1)),
|
||||
User: ptr.To(users[0]),
|
||||
UserID: new(uint(1)),
|
||||
User: new(users[0]),
|
||||
}
|
||||
|
||||
exitNode := types.Node{
|
||||
ID: 2,
|
||||
Hostname: "user2-device",
|
||||
IPv4: ap("100.64.0.2"),
|
||||
UserID: ptr.To(uint(2)),
|
||||
User: ptr.To(users[1]),
|
||||
UserID: new(uint(2)),
|
||||
User: new(users[1]),
|
||||
}
|
||||
|
||||
taggedNode := types.Node{
|
||||
ID: 3,
|
||||
Hostname: "tagged-server",
|
||||
IPv4: ap("100.64.0.3"),
|
||||
UserID: ptr.To(uint(3)),
|
||||
User: ptr.To(users[2]),
|
||||
UserID: new(uint(3)),
|
||||
User: new(users[2]),
|
||||
Tags: []string{"tag:router"},
|
||||
}
|
||||
|
||||
|
|
@ -50,8 +49,8 @@ func TestNodeCanApproveRoute(t *testing.T) {
|
|||
ID: 4,
|
||||
Hostname: "multi-tag-node",
|
||||
IPv4: ap("100.64.0.4"),
|
||||
UserID: ptr.To(uint(2)),
|
||||
User: ptr.To(users[1]),
|
||||
UserID: new(uint(2)),
|
||||
User: new(users[1]),
|
||||
Tags: []string{"tag:router", "tag:server"},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
// aliasWithPorts creates an AliasWithPorts structure from an alias and ports.
|
||||
|
|
@ -410,14 +409,14 @@ func TestCompileSSHPolicy_UserMapping(t *testing.T) {
|
|||
nodeUser1 := types.Node{
|
||||
Hostname: "user1-device",
|
||||
IPv4: createAddr("100.64.0.1"),
|
||||
UserID: ptr.To(users[0].ID),
|
||||
User: ptr.To(users[0]),
|
||||
UserID: new(users[0].ID),
|
||||
User: new(users[0]),
|
||||
}
|
||||
nodeUser2 := types.Node{
|
||||
Hostname: "user2-device",
|
||||
IPv4: createAddr("100.64.0.2"),
|
||||
UserID: ptr.To(users[1].ID),
|
||||
User: ptr.To(users[1]),
|
||||
UserID: new(users[1].ID),
|
||||
User: new(users[1]),
|
||||
}
|
||||
|
||||
nodes := types.Nodes{&nodeUser1, &nodeUser2}
|
||||
|
|
@ -622,14 +621,14 @@ func TestCompileSSHPolicy_CheckAction(t *testing.T) {
|
|||
nodeUser1 := types.Node{
|
||||
Hostname: "user1-device",
|
||||
IPv4: createAddr("100.64.0.1"),
|
||||
UserID: ptr.To(users[0].ID),
|
||||
User: ptr.To(users[0]),
|
||||
UserID: new(users[0].ID),
|
||||
User: new(users[0]),
|
||||
}
|
||||
nodeUser2 := types.Node{
|
||||
Hostname: "user2-device",
|
||||
IPv4: createAddr("100.64.0.2"),
|
||||
UserID: ptr.To(users[1].ID),
|
||||
User: ptr.To(users[1]),
|
||||
UserID: new(users[1].ID),
|
||||
User: new(users[1]),
|
||||
}
|
||||
|
||||
nodes := types.Nodes{&nodeUser1, &nodeUser2}
|
||||
|
|
@ -683,15 +682,15 @@ func TestSSHIntegrationReproduction(t *testing.T) {
|
|||
node1 := &types.Node{
|
||||
Hostname: "user1-node",
|
||||
IPv4: createAddr("100.64.0.1"),
|
||||
UserID: ptr.To(users[0].ID),
|
||||
User: ptr.To(users[0]),
|
||||
UserID: new(users[0].ID),
|
||||
User: new(users[0]),
|
||||
}
|
||||
|
||||
node2 := &types.Node{
|
||||
Hostname: "user2-node",
|
||||
IPv4: createAddr("100.64.0.2"),
|
||||
UserID: ptr.To(users[1].ID),
|
||||
User: ptr.To(users[1]),
|
||||
UserID: new(users[1].ID),
|
||||
User: new(users[1]),
|
||||
}
|
||||
|
||||
nodes := types.Nodes{node1, node2}
|
||||
|
|
@ -806,19 +805,19 @@ func TestCompileFilterRulesForNodeWithAutogroupSelf(t *testing.T) {
|
|||
|
||||
nodes := types.Nodes{
|
||||
{
|
||||
User: ptr.To(users[0]),
|
||||
User: new(users[0]),
|
||||
IPv4: ap("100.64.0.1"),
|
||||
},
|
||||
{
|
||||
User: ptr.To(users[0]),
|
||||
User: new(users[0]),
|
||||
IPv4: ap("100.64.0.2"),
|
||||
},
|
||||
{
|
||||
User: ptr.To(users[1]),
|
||||
User: new(users[1]),
|
||||
IPv4: ap("100.64.0.3"),
|
||||
},
|
||||
{
|
||||
User: ptr.To(users[1]),
|
||||
User: new(users[1]),
|
||||
IPv4: ap("100.64.0.4"),
|
||||
},
|
||||
// Tagged device for user1
|
||||
|
|
@ -938,11 +937,11 @@ func TestTagUserMutualExclusivity(t *testing.T) {
|
|||
nodes := types.Nodes{
|
||||
// User-owned nodes
|
||||
{
|
||||
User: ptr.To(users[0]),
|
||||
User: new(users[0]),
|
||||
IPv4: ap("100.64.0.1"),
|
||||
},
|
||||
{
|
||||
User: ptr.To(users[1]),
|
||||
User: new(users[1]),
|
||||
IPv4: ap("100.64.0.2"),
|
||||
},
|
||||
// Tagged nodes
|
||||
|
|
@ -960,8 +959,8 @@ func TestTagUserMutualExclusivity(t *testing.T) {
|
|||
|
||||
policy := &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:server"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:database"): Owners{ptr.To(Username("user2@"))},
|
||||
Tag("tag:server"): Owners{new(Username("user1@"))},
|
||||
Tag("tag:database"): Owners{new(Username("user2@"))},
|
||||
},
|
||||
ACLs: []ACL{
|
||||
// Rule 1: user1 (user-owned) should NOT be able to reach tagged nodes
|
||||
|
|
@ -1056,11 +1055,11 @@ func TestAutogroupTagged(t *testing.T) {
|
|||
nodes := types.Nodes{
|
||||
// User-owned nodes (not tagged)
|
||||
{
|
||||
User: ptr.To(users[0]),
|
||||
User: new(users[0]),
|
||||
IPv4: ap("100.64.0.1"),
|
||||
},
|
||||
{
|
||||
User: ptr.To(users[1]),
|
||||
User: new(users[1]),
|
||||
IPv4: ap("100.64.0.2"),
|
||||
},
|
||||
// Tagged nodes
|
||||
|
|
@ -1083,10 +1082,10 @@ func TestAutogroupTagged(t *testing.T) {
|
|||
|
||||
policy := &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:server"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:database"): Owners{ptr.To(Username("user2@"))},
|
||||
Tag("tag:web"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:prod"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:server"): Owners{new(Username("user1@"))},
|
||||
Tag("tag:database"): Owners{new(Username("user2@"))},
|
||||
Tag("tag:web"): Owners{new(Username("user1@"))},
|
||||
Tag("tag:prod"): Owners{new(Username("user1@"))},
|
||||
},
|
||||
ACLs: []ACL{
|
||||
// Rule: autogroup:tagged can reach user-owned nodes
|
||||
|
|
@ -1206,10 +1205,10 @@ func TestAutogroupSelfWithSpecificUserSource(t *testing.T) {
|
|||
}
|
||||
|
||||
nodes := types.Nodes{
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.1")},
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.2")},
|
||||
{User: ptr.To(users[1]), IPv4: ap("100.64.0.3")},
|
||||
{User: ptr.To(users[1]), IPv4: ap("100.64.0.4")},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.1")},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.2")},
|
||||
{User: new(users[1]), IPv4: ap("100.64.0.3")},
|
||||
{User: new(users[1]), IPv4: ap("100.64.0.4")},
|
||||
}
|
||||
|
||||
policy := &Policy{
|
||||
|
|
@ -1273,11 +1272,11 @@ func TestAutogroupSelfWithGroupSource(t *testing.T) {
|
|||
}
|
||||
|
||||
nodes := types.Nodes{
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.1")},
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.2")},
|
||||
{User: ptr.To(users[1]), IPv4: ap("100.64.0.3")},
|
||||
{User: ptr.To(users[1]), IPv4: ap("100.64.0.4")},
|
||||
{User: ptr.To(users[2]), IPv4: ap("100.64.0.5")},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.1")},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.2")},
|
||||
{User: new(users[1]), IPv4: ap("100.64.0.3")},
|
||||
{User: new(users[1]), IPv4: ap("100.64.0.4")},
|
||||
{User: new(users[2]), IPv4: ap("100.64.0.5")},
|
||||
}
|
||||
|
||||
policy := &Policy{
|
||||
|
|
@ -1342,13 +1341,13 @@ func TestSSHWithAutogroupSelfInDestination(t *testing.T) {
|
|||
|
||||
nodes := types.Nodes{
|
||||
// User1's nodes
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.1"), Hostname: "user1-node1"},
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.2"), Hostname: "user1-node2"},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.1"), Hostname: "user1-node1"},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.2"), Hostname: "user1-node2"},
|
||||
// User2's nodes
|
||||
{User: ptr.To(users[1]), IPv4: ap("100.64.0.3"), Hostname: "user2-node1"},
|
||||
{User: ptr.To(users[1]), IPv4: ap("100.64.0.4"), Hostname: "user2-node2"},
|
||||
{User: new(users[1]), IPv4: ap("100.64.0.3"), Hostname: "user2-node1"},
|
||||
{User: new(users[1]), IPv4: ap("100.64.0.4"), Hostname: "user2-node2"},
|
||||
// Tagged node for user1 (should be excluded)
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.5"), Hostname: "user1-tagged", Tags: []string{"tag:server"}},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.5"), Hostname: "user1-tagged", Tags: []string{"tag:server"}},
|
||||
}
|
||||
|
||||
policy := &Policy{
|
||||
|
|
@ -1420,10 +1419,10 @@ func TestSSHWithAutogroupSelfAndSpecificUser(t *testing.T) {
|
|||
}
|
||||
|
||||
nodes := types.Nodes{
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.1")},
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.2")},
|
||||
{User: ptr.To(users[1]), IPv4: ap("100.64.0.3")},
|
||||
{User: ptr.To(users[1]), IPv4: ap("100.64.0.4")},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.1")},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.2")},
|
||||
{User: new(users[1]), IPv4: ap("100.64.0.3")},
|
||||
{User: new(users[1]), IPv4: ap("100.64.0.4")},
|
||||
}
|
||||
|
||||
policy := &Policy{
|
||||
|
|
@ -1474,11 +1473,11 @@ func TestSSHWithAutogroupSelfAndGroup(t *testing.T) {
|
|||
}
|
||||
|
||||
nodes := types.Nodes{
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.1")},
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.2")},
|
||||
{User: ptr.To(users[1]), IPv4: ap("100.64.0.3")},
|
||||
{User: ptr.To(users[1]), IPv4: ap("100.64.0.4")},
|
||||
{User: ptr.To(users[2]), IPv4: ap("100.64.0.5")},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.1")},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.2")},
|
||||
{User: new(users[1]), IPv4: ap("100.64.0.3")},
|
||||
{User: new(users[1]), IPv4: ap("100.64.0.4")},
|
||||
{User: new(users[2]), IPv4: ap("100.64.0.5")},
|
||||
}
|
||||
|
||||
policy := &Policy{
|
||||
|
|
@ -1531,10 +1530,10 @@ func TestSSHWithAutogroupSelfExcludesTaggedDevices(t *testing.T) {
|
|||
}
|
||||
|
||||
nodes := types.Nodes{
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.1"), Hostname: "untagged1"},
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.2"), Hostname: "untagged2"},
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.3"), Hostname: "tagged1", Tags: []string{"tag:server"}},
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.4"), Hostname: "tagged2", Tags: []string{"tag:web"}},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.1"), Hostname: "untagged1"},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.2"), Hostname: "untagged2"},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.3"), Hostname: "tagged1", Tags: []string{"tag:server"}},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.4"), Hostname: "tagged2", Tags: []string{"tag:web"}},
|
||||
}
|
||||
|
||||
policy := &Policy{
|
||||
|
|
@ -1591,10 +1590,10 @@ func TestSSHWithAutogroupSelfAndMixedDestinations(t *testing.T) {
|
|||
}
|
||||
|
||||
nodes := types.Nodes{
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.1"), Hostname: "user1-device"},
|
||||
{User: ptr.To(users[0]), IPv4: ap("100.64.0.2"), Hostname: "user1-device2"},
|
||||
{User: ptr.To(users[1]), IPv4: ap("100.64.0.3"), Hostname: "user2-device"},
|
||||
{User: ptr.To(users[1]), IPv4: ap("100.64.0.4"), Hostname: "user2-router", Tags: []string{"tag:router"}},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.1"), Hostname: "user1-device"},
|
||||
{User: new(users[0]), IPv4: ap("100.64.0.2"), Hostname: "user1-device2"},
|
||||
{User: new(users[1]), IPv4: ap("100.64.0.3"), Hostname: "user2-device"},
|
||||
{User: new(users[1]), IPv4: ap("100.64.0.4"), Hostname: "user2-router", Tags: []string{"tag:router"}},
|
||||
}
|
||||
|
||||
policy := &Policy{
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/gorm"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
func node(name, ipv4, ipv6 string, user types.User, hostinfo *tailcfg.Hostinfo) *types.Node {
|
||||
|
|
@ -20,8 +19,8 @@ func node(name, ipv4, ipv6 string, user types.User, hostinfo *tailcfg.Hostinfo)
|
|||
Hostname: name,
|
||||
IPv4: ap(ipv4),
|
||||
IPv6: ap(ipv6),
|
||||
User: ptr.To(user),
|
||||
UserID: ptr.To(user.ID),
|
||||
User: new(user),
|
||||
UserID: new(user.ID),
|
||||
Hostinfo: hostinfo,
|
||||
}
|
||||
}
|
||||
|
|
@ -457,8 +456,8 @@ func TestAutogroupSelfWithOtherRules(t *testing.T) {
|
|||
Hostname: "test-1-device",
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: ptr.To(users[0]),
|
||||
UserID: ptr.To(users[0].ID),
|
||||
User: new(users[0]),
|
||||
UserID: new(users[0].ID),
|
||||
Hostinfo: &tailcfg.Hostinfo{},
|
||||
}
|
||||
|
||||
|
|
@ -468,8 +467,8 @@ func TestAutogroupSelfWithOtherRules(t *testing.T) {
|
|||
Hostname: "test-2-router",
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: ptr.To(users[1]),
|
||||
UserID: ptr.To(users[1].ID),
|
||||
User: new(users[1]),
|
||||
UserID: new(users[1].ID),
|
||||
Tags: []string{"tag:node-router"},
|
||||
Hostinfo: &tailcfg.Hostinfo{},
|
||||
}
|
||||
|
|
@ -537,8 +536,8 @@ func TestAutogroupSelfPolicyUpdateTriggersMapResponse(t *testing.T) {
|
|||
Hostname: "test-1-device",
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: ptr.To(users[0]),
|
||||
UserID: ptr.To(users[0].ID),
|
||||
User: new(users[0]),
|
||||
UserID: new(users[0].ID),
|
||||
Hostinfo: &tailcfg.Hostinfo{},
|
||||
}
|
||||
|
||||
|
|
@ -547,8 +546,8 @@ func TestAutogroupSelfPolicyUpdateTriggersMapResponse(t *testing.T) {
|
|||
Hostname: "test-2-device",
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: ptr.To(users[1]),
|
||||
UserID: ptr.To(users[1].ID),
|
||||
User: new(users[1]),
|
||||
UserID: new(users[1].ID),
|
||||
Hostinfo: &tailcfg.Hostinfo{},
|
||||
}
|
||||
|
||||
|
|
@ -647,8 +646,8 @@ func TestTagPropagationToPeerMap(t *testing.T) {
|
|||
Hostname: "user1-node",
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: ptr.To(users[0]),
|
||||
UserID: ptr.To(users[0].ID),
|
||||
User: new(users[0]),
|
||||
UserID: new(users[0].ID),
|
||||
Tags: []string{"tag:web", "tag:internal"},
|
||||
}
|
||||
|
||||
|
|
@ -658,8 +657,8 @@ func TestTagPropagationToPeerMap(t *testing.T) {
|
|||
Hostname: "user2-node",
|
||||
IPv4: ap("100.64.0.2"),
|
||||
IPv6: ap("fd7a:115c:a1e0::2"),
|
||||
User: ptr.To(users[1]),
|
||||
UserID: ptr.To(users[1].ID),
|
||||
User: new(users[1]),
|
||||
UserID: new(users[1].ID),
|
||||
}
|
||||
|
||||
initialNodes := types.Nodes{user1Node, user2Node}
|
||||
|
|
@ -686,8 +685,8 @@ func TestTagPropagationToPeerMap(t *testing.T) {
|
|||
Hostname: "user1-node",
|
||||
IPv4: ap("100.64.0.1"),
|
||||
IPv6: ap("fd7a:115c:a1e0::1"),
|
||||
User: ptr.To(users[0]),
|
||||
UserID: ptr.To(users[0].ID),
|
||||
User: new(users[0]),
|
||||
UserID: new(users[0].ID),
|
||||
Tags: []string{"tag:internal"}, // tag:web removed!
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import (
|
|||
"gorm.io/gorm"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
// TestUnmarshalPolicy tests the unmarshalling of JSON into Policy objects and the marshalling
|
||||
|
|
@ -53,11 +52,11 @@ func TestMarshalJSON(t *testing.T) {
|
|||
Action: "accept",
|
||||
Protocol: "tcp",
|
||||
Sources: Aliases{
|
||||
ptr.To(Username("user@example.com")),
|
||||
new(Username("user@example.com")),
|
||||
},
|
||||
Destinations: []AliasWithPorts{
|
||||
{
|
||||
Alias: ptr.To(Username("other@example.com")),
|
||||
Alias: new(Username("other@example.com")),
|
||||
Ports: []tailcfg.PortRange{{First: 80, Last: 80}},
|
||||
},
|
||||
},
|
||||
|
|
@ -253,11 +252,11 @@ func TestUnmarshalPolicy(t *testing.T) {
|
|||
Action: "accept",
|
||||
Protocol: "tcp",
|
||||
Sources: Aliases{
|
||||
ptr.To(Username("testuser@headscale.net")),
|
||||
new(Username("testuser@headscale.net")),
|
||||
},
|
||||
Destinations: []AliasWithPorts{
|
||||
{
|
||||
Alias: ptr.To(Username("otheruser@headscale.net")),
|
||||
Alias: new(Username("otheruser@headscale.net")),
|
||||
Ports: []tailcfg.PortRange{{First: 80, Last: 80}},
|
||||
},
|
||||
},
|
||||
|
|
@ -546,7 +545,7 @@ func TestUnmarshalPolicy(t *testing.T) {
|
|||
},
|
||||
Destinations: []AliasWithPorts{
|
||||
{
|
||||
Alias: ptr.To(AutoGroup("autogroup:internet")),
|
||||
Alias: new(AutoGroup("autogroup:internet")),
|
||||
Ports: []tailcfg.PortRange{tailcfg.PortRangeAny},
|
||||
},
|
||||
},
|
||||
|
|
@ -682,7 +681,7 @@ func TestUnmarshalPolicy(t *testing.T) {
|
|||
`,
|
||||
want: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:web"): Owners{ptr.To(Username("admin@example.com"))},
|
||||
Tag("tag:web"): Owners{new(Username("admin@example.com"))},
|
||||
},
|
||||
SSHs: []SSH{
|
||||
{
|
||||
|
|
@ -691,7 +690,7 @@ func TestUnmarshalPolicy(t *testing.T) {
|
|||
tp("tag:web"),
|
||||
},
|
||||
Destinations: SSHDstAliases{
|
||||
ptr.To(Username("admin@example.com")),
|
||||
new(Username("admin@example.com")),
|
||||
},
|
||||
Users: []SSHUser{
|
||||
SSHUser("*"),
|
||||
|
|
@ -733,7 +732,7 @@ func TestUnmarshalPolicy(t *testing.T) {
|
|||
gp("group:admins"),
|
||||
},
|
||||
Destinations: SSHDstAliases{
|
||||
ptr.To(Username("admin@example.com")),
|
||||
new(Username("admin@example.com")),
|
||||
},
|
||||
Users: []SSHUser{
|
||||
SSHUser("root"),
|
||||
|
|
@ -1154,7 +1153,7 @@ func TestUnmarshalPolicy(t *testing.T) {
|
|||
},
|
||||
Destinations: []AliasWithPorts{
|
||||
{
|
||||
Alias: ptr.To(AutoGroup("autogroup:internet")),
|
||||
Alias: new(AutoGroup("autogroup:internet")),
|
||||
Ports: []tailcfg.PortRange{tailcfg.PortRangeAny},
|
||||
},
|
||||
},
|
||||
|
|
@ -1491,7 +1490,7 @@ func TestUnmarshalPolicy(t *testing.T) {
|
|||
want: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:bigbrother"): {},
|
||||
Tag("tag:smallbrother"): {ptr.To(Tag("tag:bigbrother"))},
|
||||
Tag("tag:smallbrother"): {new(Tag("tag:bigbrother"))},
|
||||
},
|
||||
ACLs: []ACL{
|
||||
{
|
||||
|
|
@ -1502,7 +1501,7 @@ func TestUnmarshalPolicy(t *testing.T) {
|
|||
},
|
||||
Destinations: []AliasWithPorts{
|
||||
{
|
||||
Alias: ptr.To(Tag("tag:smallbrother")),
|
||||
Alias: new(Tag("tag:smallbrother")),
|
||||
Ports: []tailcfg.PortRange{{First: 9000, Last: 9000}},
|
||||
},
|
||||
},
|
||||
|
|
@ -1583,14 +1582,14 @@ func TestUnmarshalPolicy(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func gp(s string) *Group { return ptr.To(Group(s)) }
|
||||
func up(s string) *Username { return ptr.To(Username(s)) }
|
||||
func hp(s string) *Host { return ptr.To(Host(s)) }
|
||||
func tp(s string) *Tag { return ptr.To(Tag(s)) }
|
||||
func agp(s string) *AutoGroup { return ptr.To(AutoGroup(s)) }
|
||||
func gp(s string) *Group { return new(Group(s)) }
|
||||
func up(s string) *Username { return new(Username(s)) }
|
||||
func hp(s string) *Host { return new(Host(s)) }
|
||||
func tp(s string) *Tag { return new(Tag(s)) }
|
||||
func agp(s string) *AutoGroup { return new(AutoGroup(s)) }
|
||||
func mp(pref string) netip.Prefix { return netip.MustParsePrefix(pref) }
|
||||
func ap(addr string) *netip.Addr { return ptr.To(netip.MustParseAddr(addr)) }
|
||||
func pp(pref string) *Prefix { return ptr.To(Prefix(mp(pref))) }
|
||||
func ap(addr string) *netip.Addr { return new(netip.MustParseAddr(addr)) }
|
||||
func pp(pref string) *Prefix { return new(Prefix(mp(pref))) }
|
||||
func p(pref string) Prefix { return Prefix(mp(pref)) }
|
||||
|
||||
func TestResolvePolicy(t *testing.T) {
|
||||
|
|
@ -1636,31 +1635,31 @@ func TestResolvePolicy(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "username",
|
||||
toResolve: ptr.To(Username("testuser@")),
|
||||
toResolve: new(Username("testuser@")),
|
||||
nodes: types.Nodes{
|
||||
// Not matching other user
|
||||
{
|
||||
User: ptr.To(notme),
|
||||
User: new(notme),
|
||||
IPv4: ap("100.100.101.1"),
|
||||
},
|
||||
// Not matching forced tags
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
Tags: []string{"tag:anything"},
|
||||
IPv4: ap("100.100.101.2"),
|
||||
},
|
||||
// not matching because it's tagged (tags copied from AuthKey)
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
Tags: []string{"alsotagged"},
|
||||
IPv4: ap("100.100.101.3"),
|
||||
},
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
IPv4: ap("100.100.101.103"),
|
||||
},
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
IPv4: ap("100.100.101.104"),
|
||||
},
|
||||
},
|
||||
|
|
@ -1668,31 +1667,31 @@ func TestResolvePolicy(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "group",
|
||||
toResolve: ptr.To(Group("group:testgroup")),
|
||||
toResolve: new(Group("group:testgroup")),
|
||||
nodes: types.Nodes{
|
||||
// Not matching other user
|
||||
{
|
||||
User: ptr.To(notme),
|
||||
User: new(notme),
|
||||
IPv4: ap("100.100.101.4"),
|
||||
},
|
||||
// Not matching forced tags
|
||||
{
|
||||
User: ptr.To(groupuser),
|
||||
User: new(groupuser),
|
||||
Tags: []string{"tag:anything"},
|
||||
IPv4: ap("100.100.101.5"),
|
||||
},
|
||||
// not matching because it's tagged (tags copied from AuthKey)
|
||||
{
|
||||
User: ptr.To(groupuser),
|
||||
User: new(groupuser),
|
||||
Tags: []string{"tag:alsotagged"},
|
||||
IPv4: ap("100.100.101.6"),
|
||||
},
|
||||
{
|
||||
User: ptr.To(groupuser),
|
||||
User: new(groupuser),
|
||||
IPv4: ap("100.100.101.203"),
|
||||
},
|
||||
{
|
||||
User: ptr.To(groupuser),
|
||||
User: new(groupuser),
|
||||
IPv4: ap("100.100.101.204"),
|
||||
},
|
||||
},
|
||||
|
|
@ -1710,7 +1709,7 @@ func TestResolvePolicy(t *testing.T) {
|
|||
nodes: types.Nodes{
|
||||
// Not matching other user
|
||||
{
|
||||
User: ptr.To(notme),
|
||||
User: new(notme),
|
||||
IPv4: ap("100.100.101.9"),
|
||||
},
|
||||
// Not matching forced tags
|
||||
|
|
@ -1746,7 +1745,7 @@ func TestResolvePolicy(t *testing.T) {
|
|||
pol: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:bigbrother"): {},
|
||||
Tag("tag:smallbrother"): {ptr.To(Tag("tag:bigbrother"))},
|
||||
Tag("tag:smallbrother"): {new(Tag("tag:bigbrother"))},
|
||||
},
|
||||
},
|
||||
nodes: types.Nodes{
|
||||
|
|
@ -1769,7 +1768,7 @@ func TestResolvePolicy(t *testing.T) {
|
|||
pol: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:bigbrother"): {},
|
||||
Tag("tag:smallbrother"): {ptr.To(Tag("tag:bigbrother"))},
|
||||
Tag("tag:smallbrother"): {new(Tag("tag:bigbrother"))},
|
||||
},
|
||||
},
|
||||
nodes: types.Nodes{
|
||||
|
|
@ -1804,14 +1803,14 @@ func TestResolvePolicy(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "multiple-groups",
|
||||
toResolve: ptr.To(Group("group:testgroup")),
|
||||
toResolve: new(Group("group:testgroup")),
|
||||
nodes: types.Nodes{
|
||||
{
|
||||
User: ptr.To(groupuser1),
|
||||
User: new(groupuser1),
|
||||
IPv4: ap("100.100.101.203"),
|
||||
},
|
||||
{
|
||||
User: ptr.To(groupuser2),
|
||||
User: new(groupuser2),
|
||||
IPv4: ap("100.100.101.204"),
|
||||
},
|
||||
},
|
||||
|
|
@ -1829,10 +1828,10 @@ func TestResolvePolicy(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "invalid-username",
|
||||
toResolve: ptr.To(Username("invaliduser@")),
|
||||
toResolve: new(Username("invaliduser@")),
|
||||
nodes: types.Nodes{
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
IPv4: ap("100.100.101.103"),
|
||||
},
|
||||
},
|
||||
|
|
@ -1860,47 +1859,47 @@ func TestResolvePolicy(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "autogroup-member-comprehensive",
|
||||
toResolve: ptr.To(AutoGroup(AutoGroupMember)),
|
||||
toResolve: new(AutoGroup(AutoGroupMember)),
|
||||
nodes: types.Nodes{
|
||||
// Node with no tags (should be included - is a member)
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
IPv4: ap("100.100.101.1"),
|
||||
},
|
||||
// Node with single tag (should be excluded - tagged nodes are not members)
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
Tags: []string{"tag:test"},
|
||||
IPv4: ap("100.100.101.2"),
|
||||
},
|
||||
// Node with multiple tags, all defined in policy (should be excluded)
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
Tags: []string{"tag:test", "tag:other"},
|
||||
IPv4: ap("100.100.101.3"),
|
||||
},
|
||||
// Node with tag not defined in policy (should be excluded - still tagged)
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
Tags: []string{"tag:undefined"},
|
||||
IPv4: ap("100.100.101.4"),
|
||||
},
|
||||
// Node with mixed tags - some defined, some not (should be excluded)
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
Tags: []string{"tag:test", "tag:undefined"},
|
||||
IPv4: ap("100.100.101.5"),
|
||||
},
|
||||
// Another untagged node from different user (should be included)
|
||||
{
|
||||
User: ptr.To(testuser2),
|
||||
User: new(testuser2),
|
||||
IPv4: ap("100.100.101.6"),
|
||||
},
|
||||
},
|
||||
pol: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:test"): Owners{ptr.To(Username("testuser@"))},
|
||||
Tag("tag:other"): Owners{ptr.To(Username("testuser@"))},
|
||||
Tag("tag:test"): Owners{new(Username("testuser@"))},
|
||||
Tag("tag:other"): Owners{new(Username("testuser@"))},
|
||||
},
|
||||
},
|
||||
want: []netip.Prefix{
|
||||
|
|
@ -1910,54 +1909,54 @@ func TestResolvePolicy(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "autogroup-tagged",
|
||||
toResolve: ptr.To(AutoGroup(AutoGroupTagged)),
|
||||
toResolve: new(AutoGroup(AutoGroupTagged)),
|
||||
nodes: types.Nodes{
|
||||
// Node with no tags (should be excluded - not tagged)
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
IPv4: ap("100.100.101.1"),
|
||||
},
|
||||
// Node with single tag defined in policy (should be included)
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
Tags: []string{"tag:test"},
|
||||
IPv4: ap("100.100.101.2"),
|
||||
},
|
||||
// Node with multiple tags, all defined in policy (should be included)
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
Tags: []string{"tag:test", "tag:other"},
|
||||
IPv4: ap("100.100.101.3"),
|
||||
},
|
||||
// Node with tag not defined in policy (should be included - still tagged)
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
Tags: []string{"tag:undefined"},
|
||||
IPv4: ap("100.100.101.4"),
|
||||
},
|
||||
// Node with mixed tags - some defined, some not (should be included)
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
Tags: []string{"tag:test", "tag:undefined"},
|
||||
IPv4: ap("100.100.101.5"),
|
||||
},
|
||||
// Another untagged node from different user (should be excluded)
|
||||
{
|
||||
User: ptr.To(testuser2),
|
||||
User: new(testuser2),
|
||||
IPv4: ap("100.100.101.6"),
|
||||
},
|
||||
// Tagged node from different user (should be included)
|
||||
{
|
||||
User: ptr.To(testuser2),
|
||||
User: new(testuser2),
|
||||
Tags: []string{"tag:server"},
|
||||
IPv4: ap("100.100.101.7"),
|
||||
},
|
||||
},
|
||||
pol: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:test"): Owners{ptr.To(Username("testuser@"))},
|
||||
Tag("tag:other"): Owners{ptr.To(Username("testuser@"))},
|
||||
Tag("tag:server"): Owners{ptr.To(Username("testuser2@"))},
|
||||
Tag("tag:test"): Owners{new(Username("testuser@"))},
|
||||
Tag("tag:other"): Owners{new(Username("testuser@"))},
|
||||
Tag("tag:server"): Owners{new(Username("testuser2@"))},
|
||||
},
|
||||
},
|
||||
want: []netip.Prefix{
|
||||
|
|
@ -1968,37 +1967,37 @@ func TestResolvePolicy(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "autogroup-self",
|
||||
toResolve: ptr.To(AutoGroupSelf),
|
||||
toResolve: new(AutoGroupSelf),
|
||||
nodes: types.Nodes{
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
IPv4: ap("100.100.101.1"),
|
||||
},
|
||||
{
|
||||
User: ptr.To(testuser2),
|
||||
User: new(testuser2),
|
||||
IPv4: ap("100.100.101.2"),
|
||||
},
|
||||
{
|
||||
User: ptr.To(testuser),
|
||||
User: new(testuser),
|
||||
Tags: []string{"tag:test"},
|
||||
IPv4: ap("100.100.101.3"),
|
||||
},
|
||||
{
|
||||
User: ptr.To(testuser2),
|
||||
User: new(testuser2),
|
||||
Tags: []string{"tag:test"},
|
||||
IPv4: ap("100.100.101.4"),
|
||||
},
|
||||
},
|
||||
pol: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:test"): Owners{ptr.To(Username("testuser@"))},
|
||||
Tag("tag:test"): Owners{new(Username("testuser@"))},
|
||||
},
|
||||
},
|
||||
wantErr: "autogroup:self requires per-node resolution",
|
||||
},
|
||||
{
|
||||
name: "autogroup-invalid",
|
||||
toResolve: ptr.To(AutoGroup("autogroup:invalid")),
|
||||
toResolve: new(AutoGroup("autogroup:invalid")),
|
||||
wantErr: "unknown autogroup",
|
||||
},
|
||||
}
|
||||
|
|
@ -2076,7 +2075,7 @@ func TestResolveAutoApprovers(t *testing.T) {
|
|||
policy: &Policy{
|
||||
AutoApprovers: AutoApproverPolicy{
|
||||
Routes: map[netip.Prefix]AutoApprovers{
|
||||
mp("10.0.0.0/24"): {ptr.To(Username("user1@"))},
|
||||
mp("10.0.0.0/24"): {new(Username("user1@"))},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -2091,8 +2090,8 @@ func TestResolveAutoApprovers(t *testing.T) {
|
|||
policy: &Policy{
|
||||
AutoApprovers: AutoApproverPolicy{
|
||||
Routes: map[netip.Prefix]AutoApprovers{
|
||||
mp("10.0.0.0/24"): {ptr.To(Username("user1@"))},
|
||||
mp("10.0.1.0/24"): {ptr.To(Username("user2@"))},
|
||||
mp("10.0.0.0/24"): {new(Username("user1@"))},
|
||||
mp("10.0.1.0/24"): {new(Username("user2@"))},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -2107,7 +2106,7 @@ func TestResolveAutoApprovers(t *testing.T) {
|
|||
name: "exit-node",
|
||||
policy: &Policy{
|
||||
AutoApprovers: AutoApproverPolicy{
|
||||
ExitNode: AutoApprovers{ptr.To(Username("user1@"))},
|
||||
ExitNode: AutoApprovers{new(Username("user1@"))},
|
||||
},
|
||||
},
|
||||
want: map[netip.Prefix]*netipx.IPSet{},
|
||||
|
|
@ -2122,7 +2121,7 @@ func TestResolveAutoApprovers(t *testing.T) {
|
|||
},
|
||||
AutoApprovers: AutoApproverPolicy{
|
||||
Routes: map[netip.Prefix]AutoApprovers{
|
||||
mp("10.0.0.0/24"): {ptr.To(Group("group:testgroup"))},
|
||||
mp("10.0.0.0/24"): {new(Group("group:testgroup"))},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -2137,20 +2136,20 @@ func TestResolveAutoApprovers(t *testing.T) {
|
|||
policy: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
"tag:testtag": Owners{
|
||||
ptr.To(Username("user1@")),
|
||||
ptr.To(Username("user2@")),
|
||||
new(Username("user1@")),
|
||||
new(Username("user2@")),
|
||||
},
|
||||
"tag:exittest": Owners{
|
||||
ptr.To(Group("group:exitgroup")),
|
||||
new(Group("group:exitgroup")),
|
||||
},
|
||||
},
|
||||
Groups: Groups{
|
||||
"group:exitgroup": Usernames{"user2@"},
|
||||
},
|
||||
AutoApprovers: AutoApproverPolicy{
|
||||
ExitNode: AutoApprovers{ptr.To(Tag("tag:exittest"))},
|
||||
ExitNode: AutoApprovers{new(Tag("tag:exittest"))},
|
||||
Routes: map[netip.Prefix]AutoApprovers{
|
||||
mp("10.0.1.0/24"): {ptr.To(Tag("tag:testtag"))},
|
||||
mp("10.0.1.0/24"): {new(Tag("tag:testtag"))},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -2168,10 +2167,10 @@ func TestResolveAutoApprovers(t *testing.T) {
|
|||
},
|
||||
AutoApprovers: AutoApproverPolicy{
|
||||
Routes: map[netip.Prefix]AutoApprovers{
|
||||
mp("10.0.0.0/24"): {ptr.To(Group("group:testgroup"))},
|
||||
mp("10.0.1.0/24"): {ptr.To(Username("user3@"))},
|
||||
mp("10.0.0.0/24"): {new(Group("group:testgroup"))},
|
||||
mp("10.0.1.0/24"): {new(Username("user3@"))},
|
||||
},
|
||||
ExitNode: AutoApprovers{ptr.To(Username("user1@"))},
|
||||
ExitNode: AutoApprovers{new(Username("user1@"))},
|
||||
},
|
||||
},
|
||||
want: map[netip.Prefix]*netipx.IPSet{
|
||||
|
|
@ -2388,7 +2387,7 @@ func TestNodeCanApproveRoute(t *testing.T) {
|
|||
policy: &Policy{
|
||||
AutoApprovers: AutoApproverPolicy{
|
||||
Routes: map[netip.Prefix]AutoApprovers{
|
||||
mp("10.0.0.0/24"): {ptr.To(Username("user1@"))},
|
||||
mp("10.0.0.0/24"): {new(Username("user1@"))},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -2401,8 +2400,8 @@ func TestNodeCanApproveRoute(t *testing.T) {
|
|||
policy: &Policy{
|
||||
AutoApprovers: AutoApproverPolicy{
|
||||
Routes: map[netip.Prefix]AutoApprovers{
|
||||
mp("10.0.0.0/24"): {ptr.To(Username("user1@"))},
|
||||
mp("10.0.1.0/24"): {ptr.To(Username("user2@"))},
|
||||
mp("10.0.0.0/24"): {new(Username("user1@"))},
|
||||
mp("10.0.1.0/24"): {new(Username("user2@"))},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -2414,7 +2413,7 @@ func TestNodeCanApproveRoute(t *testing.T) {
|
|||
name: "exit-node-approval",
|
||||
policy: &Policy{
|
||||
AutoApprovers: AutoApproverPolicy{
|
||||
ExitNode: AutoApprovers{ptr.To(Username("user1@"))},
|
||||
ExitNode: AutoApprovers{new(Username("user1@"))},
|
||||
},
|
||||
},
|
||||
node: nodes[0],
|
||||
|
|
@ -2429,7 +2428,7 @@ func TestNodeCanApproveRoute(t *testing.T) {
|
|||
},
|
||||
AutoApprovers: AutoApproverPolicy{
|
||||
Routes: map[netip.Prefix]AutoApprovers{
|
||||
mp("10.0.0.0/24"): {ptr.To(Group("group:testgroup"))},
|
||||
mp("10.0.0.0/24"): {new(Group("group:testgroup"))},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -2445,10 +2444,10 @@ func TestNodeCanApproveRoute(t *testing.T) {
|
|||
},
|
||||
AutoApprovers: AutoApproverPolicy{
|
||||
Routes: map[netip.Prefix]AutoApprovers{
|
||||
mp("10.0.0.0/24"): {ptr.To(Group("group:testgroup"))},
|
||||
mp("10.0.1.0/24"): {ptr.To(Username("user3@"))},
|
||||
mp("10.0.0.0/24"): {new(Group("group:testgroup"))},
|
||||
mp("10.0.1.0/24"): {new(Username("user3@"))},
|
||||
},
|
||||
ExitNode: AutoApprovers{ptr.To(Username("user1@"))},
|
||||
ExitNode: AutoApprovers{new(Username("user1@"))},
|
||||
},
|
||||
},
|
||||
node: nodes[0],
|
||||
|
|
@ -2460,7 +2459,7 @@ func TestNodeCanApproveRoute(t *testing.T) {
|
|||
policy: &Policy{
|
||||
AutoApprovers: AutoApproverPolicy{
|
||||
Routes: map[netip.Prefix]AutoApprovers{
|
||||
mp("10.0.0.0/24"): {ptr.To(Username("user2@"))},
|
||||
mp("10.0.0.0/24"): {new(Username("user2@"))},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -2518,7 +2517,7 @@ func TestResolveTagOwners(t *testing.T) {
|
|||
name: "single-tag-owner",
|
||||
policy: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:test"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:test"): Owners{new(Username("user1@"))},
|
||||
},
|
||||
},
|
||||
want: map[Tag]*netipx.IPSet{
|
||||
|
|
@ -2530,7 +2529,7 @@ func TestResolveTagOwners(t *testing.T) {
|
|||
name: "multiple-tag-owners",
|
||||
policy: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:test"): Owners{ptr.To(Username("user1@")), ptr.To(Username("user2@"))},
|
||||
Tag("tag:test"): Owners{new(Username("user1@")), new(Username("user2@"))},
|
||||
},
|
||||
},
|
||||
want: map[Tag]*netipx.IPSet{
|
||||
|
|
@ -2545,7 +2544,7 @@ func TestResolveTagOwners(t *testing.T) {
|
|||
"group:testgroup": Usernames{"user1@", "user2@"},
|
||||
},
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:test"): Owners{ptr.To(Group("group:testgroup"))},
|
||||
Tag("tag:test"): Owners{new(Group("group:testgroup"))},
|
||||
},
|
||||
},
|
||||
want: map[Tag]*netipx.IPSet{
|
||||
|
|
@ -2557,8 +2556,8 @@ func TestResolveTagOwners(t *testing.T) {
|
|||
name: "tag-owns-tag",
|
||||
policy: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:bigbrother"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:smallbrother"): Owners{ptr.To(Tag("tag:bigbrother"))},
|
||||
Tag("tag:bigbrother"): Owners{new(Username("user1@"))},
|
||||
Tag("tag:smallbrother"): Owners{new(Tag("tag:bigbrother"))},
|
||||
},
|
||||
},
|
||||
want: map[Tag]*netipx.IPSet{
|
||||
|
|
@ -2619,7 +2618,7 @@ func TestNodeCanHaveTag(t *testing.T) {
|
|||
name: "single-tag-owner",
|
||||
policy: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:test"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:test"): Owners{new(Username("user1@"))},
|
||||
},
|
||||
},
|
||||
node: nodes[0],
|
||||
|
|
@ -2630,7 +2629,7 @@ func TestNodeCanHaveTag(t *testing.T) {
|
|||
name: "multiple-tag-owners",
|
||||
policy: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:test"): Owners{ptr.To(Username("user1@")), ptr.To(Username("user2@"))},
|
||||
Tag("tag:test"): Owners{new(Username("user1@")), new(Username("user2@"))},
|
||||
},
|
||||
},
|
||||
node: nodes[1],
|
||||
|
|
@ -2644,7 +2643,7 @@ func TestNodeCanHaveTag(t *testing.T) {
|
|||
"group:testgroup": Usernames{"user1@", "user2@"},
|
||||
},
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:test"): Owners{ptr.To(Group("group:testgroup"))},
|
||||
Tag("tag:test"): Owners{new(Group("group:testgroup"))},
|
||||
},
|
||||
},
|
||||
node: nodes[1],
|
||||
|
|
@ -2658,7 +2657,7 @@ func TestNodeCanHaveTag(t *testing.T) {
|
|||
"group:testgroup": Usernames{"invalid"},
|
||||
},
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:test"): Owners{ptr.To(Group("group:testgroup"))},
|
||||
Tag("tag:test"): Owners{new(Group("group:testgroup"))},
|
||||
},
|
||||
},
|
||||
node: nodes[0],
|
||||
|
|
@ -2670,7 +2669,7 @@ func TestNodeCanHaveTag(t *testing.T) {
|
|||
name: "node-cannot-have-tag",
|
||||
policy: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:test"): Owners{ptr.To(Username("user2@"))},
|
||||
Tag("tag:test"): Owners{new(Username("user2@"))},
|
||||
},
|
||||
},
|
||||
node: nodes[0],
|
||||
|
|
@ -2681,7 +2680,7 @@ func TestNodeCanHaveTag(t *testing.T) {
|
|||
name: "node-with-unauthorized-tag-different-user",
|
||||
policy: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:prod"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:prod"): Owners{new(Username("user1@"))},
|
||||
},
|
||||
},
|
||||
node: nodes[2], // user3's node
|
||||
|
|
@ -2692,8 +2691,8 @@ func TestNodeCanHaveTag(t *testing.T) {
|
|||
name: "node-with-multiple-tags-one-unauthorized",
|
||||
policy: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:web"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:database"): Owners{ptr.To(Username("user2@"))},
|
||||
Tag("tag:web"): Owners{new(Username("user1@"))},
|
||||
Tag("tag:database"): Owners{new(Username("user2@"))},
|
||||
},
|
||||
},
|
||||
node: nodes[0], // user1's node
|
||||
|
|
@ -2713,7 +2712,7 @@ func TestNodeCanHaveTag(t *testing.T) {
|
|||
name: "tag-not-in-tagowners",
|
||||
policy: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:prod"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:prod"): Owners{new(Username("user1@"))},
|
||||
},
|
||||
},
|
||||
node: nodes[0],
|
||||
|
|
@ -2726,13 +2725,13 @@ func TestNodeCanHaveTag(t *testing.T) {
|
|||
name: "node-without-ip-user-owns-tag",
|
||||
policy: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:test"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:test"): Owners{new(Username("user1@"))},
|
||||
},
|
||||
},
|
||||
node: &types.Node{
|
||||
// No IPv4 or IPv6 - simulates new node registration
|
||||
User: &users[0],
|
||||
UserID: ptr.To(users[0].ID),
|
||||
UserID: new(users[0].ID),
|
||||
},
|
||||
tag: "tag:test",
|
||||
want: true, // Should succeed via user-based fallback
|
||||
|
|
@ -2741,13 +2740,13 @@ func TestNodeCanHaveTag(t *testing.T) {
|
|||
name: "node-without-ip-user-does-not-own-tag",
|
||||
policy: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:test"): Owners{ptr.To(Username("user2@"))},
|
||||
Tag("tag:test"): Owners{new(Username("user2@"))},
|
||||
},
|
||||
},
|
||||
node: &types.Node{
|
||||
// No IPv4 or IPv6 - simulates new node registration
|
||||
User: &users[0], // user1, but tag owned by user2
|
||||
UserID: ptr.To(users[0].ID),
|
||||
UserID: new(users[0].ID),
|
||||
},
|
||||
tag: "tag:test",
|
||||
want: false, // user1 does not own tag:test
|
||||
|
|
@ -2759,13 +2758,13 @@ func TestNodeCanHaveTag(t *testing.T) {
|
|||
"group:admins": Usernames{"user1@", "user2@"},
|
||||
},
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:admin"): Owners{ptr.To(Group("group:admins"))},
|
||||
Tag("tag:admin"): Owners{new(Group("group:admins"))},
|
||||
},
|
||||
},
|
||||
node: &types.Node{
|
||||
// No IPv4 or IPv6 - simulates new node registration
|
||||
User: &users[1], // user2 is in group:admins
|
||||
UserID: ptr.To(users[1].ID),
|
||||
UserID: new(users[1].ID),
|
||||
},
|
||||
tag: "tag:admin",
|
||||
want: true, // Should succeed via group membership
|
||||
|
|
@ -2777,13 +2776,13 @@ func TestNodeCanHaveTag(t *testing.T) {
|
|||
"group:admins": Usernames{"user1@"},
|
||||
},
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:admin"): Owners{ptr.To(Group("group:admins"))},
|
||||
Tag("tag:admin"): Owners{new(Group("group:admins"))},
|
||||
},
|
||||
},
|
||||
node: &types.Node{
|
||||
// No IPv4 or IPv6 - simulates new node registration
|
||||
User: &users[1], // user2 is NOT in group:admins
|
||||
UserID: ptr.To(users[1].ID),
|
||||
UserID: new(users[1].ID),
|
||||
},
|
||||
tag: "tag:admin",
|
||||
want: false, // user2 is not in group:admins
|
||||
|
|
@ -2792,7 +2791,7 @@ func TestNodeCanHaveTag(t *testing.T) {
|
|||
name: "node-without-ip-no-user",
|
||||
policy: &Policy{
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:test"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:test"): Owners{new(Username("user1@"))},
|
||||
},
|
||||
},
|
||||
node: &types.Node{
|
||||
|
|
@ -2809,14 +2808,14 @@ func TestNodeCanHaveTag(t *testing.T) {
|
|||
},
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:server"): Owners{
|
||||
ptr.To(Username("user1@")),
|
||||
ptr.To(Group("group:ops")),
|
||||
new(Username("user1@")),
|
||||
new(Group("group:ops")),
|
||||
},
|
||||
},
|
||||
},
|
||||
node: &types.Node{
|
||||
User: &users[0], // user1 directly owns the tag
|
||||
UserID: ptr.To(users[0].ID),
|
||||
UserID: new(users[0].ID),
|
||||
},
|
||||
tag: "tag:server",
|
||||
want: true,
|
||||
|
|
@ -2829,14 +2828,14 @@ func TestNodeCanHaveTag(t *testing.T) {
|
|||
},
|
||||
TagOwners: TagOwners{
|
||||
Tag("tag:server"): Owners{
|
||||
ptr.To(Username("user1@")),
|
||||
ptr.To(Group("group:ops")),
|
||||
new(Username("user1@")),
|
||||
new(Group("group:ops")),
|
||||
},
|
||||
},
|
||||
},
|
||||
node: &types.Node{
|
||||
User: &users[2], // user3 is in group:ops
|
||||
UserID: ptr.To(users[2].ID),
|
||||
UserID: new(users[2].ID),
|
||||
},
|
||||
tag: "tag:server",
|
||||
want: true,
|
||||
|
|
@ -2881,14 +2880,14 @@ func TestUserMatchesOwner(t *testing.T) {
|
|||
name: "username-match",
|
||||
policy: &Policy{},
|
||||
user: users[0],
|
||||
owner: ptr.To(Username("user1@")),
|
||||
owner: new(Username("user1@")),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "username-no-match",
|
||||
policy: &Policy{},
|
||||
user: users[0],
|
||||
owner: ptr.To(Username("user2@")),
|
||||
owner: new(Username("user2@")),
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
|
|
@ -2899,7 +2898,7 @@ func TestUserMatchesOwner(t *testing.T) {
|
|||
},
|
||||
},
|
||||
user: users[1], // user2 is in group:admins
|
||||
owner: ptr.To(Group("group:admins")),
|
||||
owner: new(Group("group:admins")),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
|
|
@ -2910,7 +2909,7 @@ func TestUserMatchesOwner(t *testing.T) {
|
|||
},
|
||||
},
|
||||
user: users[1], // user2 is NOT in group:admins
|
||||
owner: ptr.To(Group("group:admins")),
|
||||
owner: new(Group("group:admins")),
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
|
|
@ -2919,7 +2918,7 @@ func TestUserMatchesOwner(t *testing.T) {
|
|||
Groups: Groups{},
|
||||
},
|
||||
user: users[0],
|
||||
owner: ptr.To(Group("group:undefined")),
|
||||
owner: new(Group("group:undefined")),
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
|
|
@ -3261,20 +3260,20 @@ func TestFlattenTagOwners(t *testing.T) {
|
|||
{
|
||||
name: "tag-owns-tag",
|
||||
input: TagOwners{
|
||||
Tag("tag:bigbrother"): Owners{ptr.To(Group("group:user1"))},
|
||||
Tag("tag:smallbrother"): Owners{ptr.To(Tag("tag:bigbrother"))},
|
||||
Tag("tag:bigbrother"): Owners{new(Group("group:user1"))},
|
||||
Tag("tag:smallbrother"): Owners{new(Tag("tag:bigbrother"))},
|
||||
},
|
||||
want: TagOwners{
|
||||
Tag("tag:bigbrother"): Owners{ptr.To(Group("group:user1"))},
|
||||
Tag("tag:smallbrother"): Owners{ptr.To(Group("group:user1"))},
|
||||
Tag("tag:bigbrother"): Owners{new(Group("group:user1"))},
|
||||
Tag("tag:smallbrother"): Owners{new(Group("group:user1"))},
|
||||
},
|
||||
wantErr: "",
|
||||
},
|
||||
{
|
||||
name: "circular-reference",
|
||||
input: TagOwners{
|
||||
Tag("tag:a"): Owners{ptr.To(Tag("tag:b"))},
|
||||
Tag("tag:b"): Owners{ptr.To(Tag("tag:a"))},
|
||||
Tag("tag:a"): Owners{new(Tag("tag:b"))},
|
||||
Tag("tag:b"): Owners{new(Tag("tag:a"))},
|
||||
},
|
||||
want: nil,
|
||||
wantErr: "circular reference detected: tag:a -> tag:b",
|
||||
|
|
@ -3282,83 +3281,83 @@ func TestFlattenTagOwners(t *testing.T) {
|
|||
{
|
||||
name: "mixed-owners",
|
||||
input: TagOwners{
|
||||
Tag("tag:x"): Owners{ptr.To(Username("user1@")), ptr.To(Tag("tag:y"))},
|
||||
Tag("tag:y"): Owners{ptr.To(Username("user2@"))},
|
||||
Tag("tag:x"): Owners{new(Username("user1@")), new(Tag("tag:y"))},
|
||||
Tag("tag:y"): Owners{new(Username("user2@"))},
|
||||
},
|
||||
want: TagOwners{
|
||||
Tag("tag:x"): Owners{ptr.To(Username("user1@")), ptr.To(Username("user2@"))},
|
||||
Tag("tag:y"): Owners{ptr.To(Username("user2@"))},
|
||||
Tag("tag:x"): Owners{new(Username("user1@")), new(Username("user2@"))},
|
||||
Tag("tag:y"): Owners{new(Username("user2@"))},
|
||||
},
|
||||
wantErr: "",
|
||||
},
|
||||
{
|
||||
name: "mixed-dupe-owners",
|
||||
input: TagOwners{
|
||||
Tag("tag:x"): Owners{ptr.To(Username("user1@")), ptr.To(Tag("tag:y"))},
|
||||
Tag("tag:y"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:x"): Owners{new(Username("user1@")), new(Tag("tag:y"))},
|
||||
Tag("tag:y"): Owners{new(Username("user1@"))},
|
||||
},
|
||||
want: TagOwners{
|
||||
Tag("tag:x"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:y"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:x"): Owners{new(Username("user1@"))},
|
||||
Tag("tag:y"): Owners{new(Username("user1@"))},
|
||||
},
|
||||
wantErr: "",
|
||||
},
|
||||
{
|
||||
name: "no-tag-owners",
|
||||
input: TagOwners{
|
||||
Tag("tag:solo"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:solo"): Owners{new(Username("user1@"))},
|
||||
},
|
||||
want: TagOwners{
|
||||
Tag("tag:solo"): Owners{ptr.To(Username("user1@"))},
|
||||
Tag("tag:solo"): Owners{new(Username("user1@"))},
|
||||
},
|
||||
wantErr: "",
|
||||
},
|
||||
{
|
||||
name: "tag-long-owner-chain",
|
||||
input: TagOwners{
|
||||
Tag("tag:a"): Owners{ptr.To(Group("group:user1"))},
|
||||
Tag("tag:b"): Owners{ptr.To(Tag("tag:a"))},
|
||||
Tag("tag:c"): Owners{ptr.To(Tag("tag:b"))},
|
||||
Tag("tag:d"): Owners{ptr.To(Tag("tag:c"))},
|
||||
Tag("tag:e"): Owners{ptr.To(Tag("tag:d"))},
|
||||
Tag("tag:f"): Owners{ptr.To(Tag("tag:e"))},
|
||||
Tag("tag:g"): Owners{ptr.To(Tag("tag:f"))},
|
||||
Tag("tag:a"): Owners{new(Group("group:user1"))},
|
||||
Tag("tag:b"): Owners{new(Tag("tag:a"))},
|
||||
Tag("tag:c"): Owners{new(Tag("tag:b"))},
|
||||
Tag("tag:d"): Owners{new(Tag("tag:c"))},
|
||||
Tag("tag:e"): Owners{new(Tag("tag:d"))},
|
||||
Tag("tag:f"): Owners{new(Tag("tag:e"))},
|
||||
Tag("tag:g"): Owners{new(Tag("tag:f"))},
|
||||
},
|
||||
want: TagOwners{
|
||||
Tag("tag:a"): Owners{ptr.To(Group("group:user1"))},
|
||||
Tag("tag:b"): Owners{ptr.To(Group("group:user1"))},
|
||||
Tag("tag:c"): Owners{ptr.To(Group("group:user1"))},
|
||||
Tag("tag:d"): Owners{ptr.To(Group("group:user1"))},
|
||||
Tag("tag:e"): Owners{ptr.To(Group("group:user1"))},
|
||||
Tag("tag:f"): Owners{ptr.To(Group("group:user1"))},
|
||||
Tag("tag:g"): Owners{ptr.To(Group("group:user1"))},
|
||||
Tag("tag:a"): Owners{new(Group("group:user1"))},
|
||||
Tag("tag:b"): Owners{new(Group("group:user1"))},
|
||||
Tag("tag:c"): Owners{new(Group("group:user1"))},
|
||||
Tag("tag:d"): Owners{new(Group("group:user1"))},
|
||||
Tag("tag:e"): Owners{new(Group("group:user1"))},
|
||||
Tag("tag:f"): Owners{new(Group("group:user1"))},
|
||||
Tag("tag:g"): Owners{new(Group("group:user1"))},
|
||||
},
|
||||
wantErr: "",
|
||||
},
|
||||
{
|
||||
name: "tag-long-circular-chain",
|
||||
input: TagOwners{
|
||||
Tag("tag:a"): Owners{ptr.To(Tag("tag:g"))},
|
||||
Tag("tag:b"): Owners{ptr.To(Tag("tag:a"))},
|
||||
Tag("tag:c"): Owners{ptr.To(Tag("tag:b"))},
|
||||
Tag("tag:d"): Owners{ptr.To(Tag("tag:c"))},
|
||||
Tag("tag:e"): Owners{ptr.To(Tag("tag:d"))},
|
||||
Tag("tag:f"): Owners{ptr.To(Tag("tag:e"))},
|
||||
Tag("tag:g"): Owners{ptr.To(Tag("tag:f"))},
|
||||
Tag("tag:a"): Owners{new(Tag("tag:g"))},
|
||||
Tag("tag:b"): Owners{new(Tag("tag:a"))},
|
||||
Tag("tag:c"): Owners{new(Tag("tag:b"))},
|
||||
Tag("tag:d"): Owners{new(Tag("tag:c"))},
|
||||
Tag("tag:e"): Owners{new(Tag("tag:d"))},
|
||||
Tag("tag:f"): Owners{new(Tag("tag:e"))},
|
||||
Tag("tag:g"): Owners{new(Tag("tag:f"))},
|
||||
},
|
||||
wantErr: "circular reference detected: tag:a -> tag:b -> tag:c -> tag:d -> tag:e -> tag:f -> tag:g",
|
||||
},
|
||||
{
|
||||
name: "undefined-tag-reference",
|
||||
input: TagOwners{
|
||||
Tag("tag:a"): Owners{ptr.To(Tag("tag:nonexistent"))},
|
||||
Tag("tag:a"): Owners{new(Tag("tag:nonexistent"))},
|
||||
},
|
||||
wantErr: `tag "tag:a" references undefined tag "tag:nonexistent"`,
|
||||
},
|
||||
{
|
||||
name: "tag-with-empty-owners-is-valid",
|
||||
input: TagOwners{
|
||||
Tag("tag:a"): Owners{ptr.To(Tag("tag:b"))},
|
||||
Tag("tag:a"): Owners{new(Tag("tag:b"))},
|
||||
Tag("tag:b"): Owners{}, // empty owners but exists
|
||||
},
|
||||
want: TagOwners{
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/juanfont/headscale/hscontrol/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
// TestEphemeralNodeDeleteWithConcurrentUpdate tests the race condition where UpdateNode and DeleteNode
|
||||
|
|
@ -50,7 +49,7 @@ func TestEphemeralNodeDeleteWithConcurrentUpdate(t *testing.T) {
|
|||
// Goroutine 1: UpdateNode (simulates UpdateNodeFromMapRequest)
|
||||
go func() {
|
||||
updatedNode, updateOk = store.UpdateNode(node.ID, func(n *types.Node) {
|
||||
n.LastSeen = ptr.To(time.Now())
|
||||
n.LastSeen = new(time.Now())
|
||||
})
|
||||
done <- true
|
||||
}()
|
||||
|
|
@ -106,7 +105,7 @@ func TestUpdateNodeReturnsInvalidWhenDeletedInSameBatch(t *testing.T) {
|
|||
// Start UpdateNode in goroutine - it will queue and wait for batch
|
||||
go func() {
|
||||
node, ok := store.UpdateNode(node.ID, func(n *types.Node) {
|
||||
n.LastSeen = ptr.To(time.Now())
|
||||
n.LastSeen = new(time.Now())
|
||||
})
|
||||
resultChan <- struct {
|
||||
node types.NodeView
|
||||
|
|
@ -156,7 +155,7 @@ func TestPersistNodeToDBPreventsRaceCondition(t *testing.T) {
|
|||
|
||||
// Simulate UpdateNode being called
|
||||
updatedNode, ok := store.UpdateNode(node.ID, func(n *types.Node) {
|
||||
n.LastSeen = ptr.To(time.Now())
|
||||
n.LastSeen = new(time.Now())
|
||||
})
|
||||
require.True(t, ok, "UpdateNode should succeed")
|
||||
require.True(t, updatedNode.Valid(), "UpdateNode should return valid node")
|
||||
|
|
@ -221,7 +220,7 @@ func TestEphemeralNodeLogoutRaceCondition(t *testing.T) {
|
|||
// Goroutine 1: UpdateNode (simulates UpdateNodeFromMapRequest)
|
||||
go func() {
|
||||
updatedNode, updateOk = store.UpdateNode(ephemeralNode.ID, func(n *types.Node) {
|
||||
n.LastSeen = ptr.To(time.Now())
|
||||
n.LastSeen = new(time.Now())
|
||||
})
|
||||
done <- true
|
||||
}()
|
||||
|
|
@ -294,7 +293,7 @@ func TestUpdateNodeFromMapRequestEphemeralLogoutSequence(t *testing.T) {
|
|||
|
||||
go func() {
|
||||
node, ok := store.UpdateNode(ephemeralNode.ID, func(n *types.Node) {
|
||||
n.LastSeen = ptr.To(time.Now())
|
||||
n.LastSeen = new(time.Now())
|
||||
endpoint := netip.MustParseAddrPort("10.0.0.1:41641")
|
||||
n.Endpoints = []netip.AddrPort{endpoint}
|
||||
})
|
||||
|
|
@ -363,7 +362,7 @@ func TestUpdateNodeDeletedInSameBatchReturnsInvalid(t *testing.T) {
|
|||
|
||||
go func() {
|
||||
updatedNode, ok := store.UpdateNode(node.ID, func(n *types.Node) {
|
||||
n.LastSeen = ptr.To(time.Now())
|
||||
n.LastSeen = new(time.Now())
|
||||
})
|
||||
updateDone <- struct {
|
||||
node types.NodeView
|
||||
|
|
@ -417,7 +416,7 @@ func TestPersistNodeToDBChecksNodeStoreBeforePersist(t *testing.T) {
|
|||
|
||||
// UpdateNode returns a node
|
||||
updatedNode, ok := store.UpdateNode(ephemeralNode.ID, func(n *types.Node) {
|
||||
n.LastSeen = ptr.To(time.Now())
|
||||
n.LastSeen = new(time.Now())
|
||||
})
|
||||
require.True(t, ok, "UpdateNode should succeed")
|
||||
require.True(t, updatedNode.Valid(), "updated node should be valid")
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
func TestNetInfoFromMapRequest(t *testing.T) {
|
||||
|
|
@ -149,7 +148,7 @@ func createTestNodeSimple(id types.NodeID) *types.Node {
|
|||
node := &types.Node{
|
||||
ID: id,
|
||||
Hostname: "test-node",
|
||||
UserID: ptr.To(uint(id)),
|
||||
UserID: new(uint(id)),
|
||||
User: &user,
|
||||
MachineKey: machineKey.Public(),
|
||||
NodeKey: nodeKey.Public(),
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
func TestSnapshotFromNodes(t *testing.T) {
|
||||
|
|
@ -174,7 +173,7 @@ func createTestNode(nodeID types.NodeID, userID uint, username, hostname string)
|
|||
DiscoKey: discoKey.Public(),
|
||||
Hostname: hostname,
|
||||
GivenName: hostname,
|
||||
UserID: ptr.To(userID),
|
||||
UserID: new(userID),
|
||||
User: &types.User{
|
||||
Name: username,
|
||||
DisplayName: username,
|
||||
|
|
@ -856,7 +855,7 @@ func createConcurrentTestNode(id types.NodeID, hostname string) types.Node {
|
|||
Hostname: hostname,
|
||||
MachineKey: machineKey.Public(),
|
||||
NodeKey: nodeKey.Public(),
|
||||
UserID: ptr.To(uint(1)),
|
||||
UserID: new(uint(1)),
|
||||
User: &types.User{
|
||||
Name: "concurrent-test-user",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import (
|
|||
"github.com/juanfont/headscale/hscontrol/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gorm.io/gorm"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
// TestNodeIsTagged tests the IsTagged() method for determining if a node is tagged.
|
||||
|
|
@ -69,7 +68,7 @@ func TestNodeIsTagged(t *testing.T) {
|
|||
{
|
||||
name: "node with user and no tags - not tagged",
|
||||
node: Node{
|
||||
UserID: ptr.To(uint(42)),
|
||||
UserID: new(uint(42)),
|
||||
Tags: []string{},
|
||||
},
|
||||
want: false,
|
||||
|
|
@ -112,7 +111,7 @@ func TestNodeViewIsTagged(t *testing.T) {
|
|||
{
|
||||
name: "user-owned node",
|
||||
node: Node{
|
||||
UserID: ptr.To(uint(1)),
|
||||
UserID: new(uint(1)),
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
|
|
@ -223,7 +222,7 @@ func TestNodeTagsImmutableAfterRegistration(t *testing.T) {
|
|||
// Test that a user-owned node is not tagged
|
||||
userNode := Node{
|
||||
ID: 2,
|
||||
UserID: ptr.To(uint(42)),
|
||||
UserID: new(uint(42)),
|
||||
Tags: []string{},
|
||||
RegisterMethod: util.RegisterMethodOIDC,
|
||||
}
|
||||
|
|
@ -243,7 +242,7 @@ func TestNodeOwnershipModel(t *testing.T) {
|
|||
name: "tagged node has tags, UserID is informational",
|
||||
node: Node{
|
||||
ID: 1,
|
||||
UserID: ptr.To(uint(5)), // "created by" user 5
|
||||
UserID: new(uint(5)), // "created by" user 5
|
||||
Tags: []string{"tag:server"},
|
||||
},
|
||||
wantIsTagged: true,
|
||||
|
|
@ -253,7 +252,7 @@ func TestNodeOwnershipModel(t *testing.T) {
|
|||
name: "user-owned node has no tags",
|
||||
node: Node{
|
||||
ID: 2,
|
||||
UserID: ptr.To(uint(5)),
|
||||
UserID: new(uint(5)),
|
||||
Tags: []string{},
|
||||
},
|
||||
wantIsTagged: false,
|
||||
|
|
@ -265,7 +264,7 @@ func TestNodeOwnershipModel(t *testing.T) {
|
|||
name: "node with only authkey tags - not tagged (tags should be copied)",
|
||||
node: Node{
|
||||
ID: 3,
|
||||
UserID: ptr.To(uint(5)), // "created by" user 5
|
||||
UserID: new(uint(5)), // "created by" user 5
|
||||
AuthKey: &PreAuthKey{
|
||||
Tags: []string{"tag:database"},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ func (u *User) StringID() string {
|
|||
}
|
||||
|
||||
// TypedID returns a pointer to the user's ID as a UserID type.
|
||||
// This is a convenience method to avoid ugly casting like ptr.To(types.UserID(user.ID)).
|
||||
// This is a convenience method to avoid ugly casting like new(types.UserID(user.ID)).
|
||||
func (u *User) TypedID() *UserID {
|
||||
uid := UserID(u.ID)
|
||||
return &uid
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
var veryLargeDestination = []policyv2.AliasWithPorts{
|
||||
|
|
@ -1284,9 +1283,9 @@ func TestACLAutogroupMember(t *testing.T) {
|
|||
ACLs: []policyv2.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []policyv2.Alias{ptr.To(policyv2.AutoGroupMember)},
|
||||
Sources: []policyv2.Alias{new(policyv2.AutoGroupMember)},
|
||||
Destinations: []policyv2.AliasWithPorts{
|
||||
aliasWithPorts(ptr.To(policyv2.AutoGroupMember), tailcfg.PortRangeAny),
|
||||
aliasWithPorts(new(policyv2.AutoGroupMember), tailcfg.PortRangeAny),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -1372,9 +1371,9 @@ func TestACLAutogroupTagged(t *testing.T) {
|
|||
ACLs: []policyv2.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []policyv2.Alias{ptr.To(policyv2.AutoGroupTagged)},
|
||||
Sources: []policyv2.Alias{new(policyv2.AutoGroupTagged)},
|
||||
Destinations: []policyv2.AliasWithPorts{
|
||||
aliasWithPorts(ptr.To(policyv2.AutoGroupTagged), tailcfg.PortRangeAny),
|
||||
aliasWithPorts(new(policyv2.AutoGroupTagged), tailcfg.PortRangeAny),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -1657,9 +1656,9 @@ func TestACLAutogroupSelf(t *testing.T) {
|
|||
ACLs: []policyv2.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []policyv2.Alias{ptr.To(policyv2.AutoGroupMember)},
|
||||
Sources: []policyv2.Alias{new(policyv2.AutoGroupMember)},
|
||||
Destinations: []policyv2.AliasWithPorts{
|
||||
aliasWithPorts(ptr.To(policyv2.AutoGroupSelf), tailcfg.PortRangeAny),
|
||||
aliasWithPorts(new(policyv2.AutoGroupSelf), tailcfg.PortRangeAny),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1956,9 +1955,9 @@ func TestACLPolicyPropagationOverTime(t *testing.T) {
|
|||
ACLs: []policyv2.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []policyv2.Alias{ptr.To(policyv2.AutoGroupMember)},
|
||||
Sources: []policyv2.Alias{new(policyv2.AutoGroupMember)},
|
||||
Destinations: []policyv2.AliasWithPorts{
|
||||
aliasWithPorts(ptr.To(policyv2.AutoGroupSelf), tailcfg.PortRangeAny),
|
||||
aliasWithPorts(new(policyv2.AutoGroupSelf), tailcfg.PortRangeAny),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -356,13 +356,13 @@ func TestAPIAuthenticationBypassCurl(t *testing.T) {
|
|||
|
||||
lines := strings.Split(curlOutput, "\n")
|
||||
var httpCode string
|
||||
var responseBody string
|
||||
var responseBody strings.Builder
|
||||
|
||||
for _, line := range lines {
|
||||
if after, ok := strings.CutPrefix(line, "HTTP_CODE:"); ok {
|
||||
httpCode = after
|
||||
} else {
|
||||
responseBody += line
|
||||
responseBody.WriteString(line)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -372,7 +372,7 @@ func TestAPIAuthenticationBypassCurl(t *testing.T) {
|
|||
|
||||
// Should contain user data
|
||||
var response v1.ListUsersResponse
|
||||
err = protojson.Unmarshal([]byte(responseBody), &response)
|
||||
err = protojson.Unmarshal([]byte(responseBody.String()), &response)
|
||||
assert.NoError(t, err, "Response should be valid protobuf JSON")
|
||||
users := response.GetUsers()
|
||||
assert.Len(t, users, 2, "Should have 2 users")
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
func TestAuthKeyLogoutAndReloginSameUser(t *testing.T) {
|
||||
|
|
@ -608,7 +607,7 @@ func TestAuthKeyLogoutAndReloginRoutesPreserved(t *testing.T) {
|
|||
},
|
||||
AutoApprovers: policyv2.AutoApproverPolicy{
|
||||
Routes: map[netip.Prefix]policyv2.AutoApprovers{
|
||||
netip.MustParsePrefix(advertiseRoute): {ptr.To(policyv2.Username(user + "@test.no"))},
|
||||
netip.MustParsePrefix(advertiseRoute): {new(policyv2.Username(user + "@test.no"))},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
func isSSHNoAccessStdError(stderr string) bool {
|
||||
|
|
@ -482,10 +481,10 @@ func TestSSHAutogroupSelf(t *testing.T) {
|
|||
{
|
||||
Action: "accept",
|
||||
Sources: policyv2.SSHSrcAliases{
|
||||
ptr.To(policyv2.AutoGroupMember),
|
||||
new(policyv2.AutoGroupMember),
|
||||
},
|
||||
Destinations: policyv2.SSHDstAliases{
|
||||
ptr.To(policyv2.AutoGroupSelf),
|
||||
new(policyv2.AutoGroupSelf),
|
||||
},
|
||||
Users: []policyv2.SSHUser{policyv2.SSHUser("ssh-it-user")},
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue